On Sun, 28 May 2023 at 00:15:26 +0100, Simon McVittie wrote:
>   [x] attach debdiff against the package in [bookworm]

Sorry, here's the diff.

The attached diff is between patched trees, excluding the patches
themselves to avoid duplicating the changes, and is lightly filtered
to ignore translations (very verbose). I normally upload using dgit,
so if I'm the uploader, the uploaded .dsc will be checked for an exact
match to what's in git.

GNOME team (particularly Jeremy and Marco): This and the accompanying
gnome-shell update are particularly high-visibility and important to get
right, and the finer points of compositor behaviour are not my strong
point, so please check this. I have uploaded prerelease packages to
<https://people.debian.org/~smcv/12.1/> and will upload to unstable if
given permission. If someone with more compositor expertise wants to
take these over, they are very welcome to do so.

    smcv
git diff patch-queue/43.4.. | filterdiff -p1 -x'debian/patches/*.patch' -x'po/*.po'

diff --git a/NEWS b/NEWS
index 65e5d1cf8..27862914b 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,15 @@
+43.5
+====
+* Fix recording windows on non-active workspaces [Robert; !2789]
+* Fixed crashes [Colin, Sebastian, Jonas; !2917, !2955, !2969]
+* Misc. bug fixes and cleanups [Ivan; !2928]
+
+Contributors:
+  Jonas Ã…dahl, Sebastian Keller, Colin Kinloch, Robert Mader, Ivan Molodetskikh
+
+Translators:
+  Nart Tlisha [ab]
+
 43.4
 ====
 * Do not overwrite previously set offsets on attach [Matthias; !2843]
diff --git a/debian/changelog b/debian/changelog
index d7daed123..1440b273e 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,27 @@
+mutter (43.5-0+deb12u1) UNRELEASED; urgency=medium
+
+  * New upstream stable release
+    - Always update surfaces belonging to a window that is being recorded
+      or included in a screencast, even if the window is not visible
+      on a local display (mutter#2538, mutter!2789)
+    - Export previously-private meta_window_has_pointer(), needed by
+      screenshot UI fixes in gnome-shell 43.5 (mutter!2928)
+      + d/libmutter-11-0.symbols: Update to add that symbol
+    - All other changes were already present in 43.4-2
+  * d/patches: Drop patches that were applied upstream
+  * d/patches: Update to upstream gnome-43 branch commit 43.5-2-g8d7e958b8
+    for additional post-release fixes
+    - d/p/compositor-view-Chain-up-finalize.patch:
+      Fix a resource leak when a compositor view is destroyed (mutter!2991)
+    - d/p/wayland-xdg-shell-Dismiss-instead-of-destroy-invalid-popu.patch:
+      Update metadata to reflect upstream backport, no functional change
+  * d/p/wayland-outputs-Fix-potential-crash-when-output-has-no-mo.patch:
+    Backport patch from 44~beta to fix a crash during suspend/resume in
+    some circumstances (mutter#2570, potentially also resolves
+    #1010478 and #1036268)
+
+ -- Simon McVittie <s...@debian.org>  Sat, 27 May 2023 15:46:33 +0100
+
 mutter (43.4-2) unstable; urgency=medium
 
   * Team upload
diff --git a/debian/libmutter-11-0.symbols b/debian/libmutter-11-0.symbols
index 1128f2ab3..f3b181d85 100644
--- a/debian/libmutter-11-0.symbols
+++ b/debian/libmutter-11-0.symbols
@@ -780,6 +780,7 @@ libmutter-11.so.0 libmutter-11-0 #MINVER#
  meta_window_group_leader_changed@Base 43.0
  meta_window_has_attached_dialogs@Base 43.0
  meta_window_has_focus@Base 43.0
+ meta_window_has_pointer@Base 43.5
  meta_window_is_above@Base 43.0
  meta_window_is_always_on_all_workspaces@Base 43.0
  meta_window_is_ancestor_of_transient@Base 43.0
diff --git a/debian/patches/compositor-view-Chain-up-finalize.patch b/debian/patches/compositor-view-Chain-up-finalize.patch
new file mode 100644
index 000000000..383a1065d
diff --git a/debian/patches/series b/debian/patches/series
index 8be32b377..3068ed91d 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -1,9 +1,6 @@
-wayland-Skip-subsurface-desync-if-parent-is-NULL.patch
-Update-Abkhazian-translation.patch
-clutter-actor-Get-next-action-from-list-before-handling-c.patch
-cursor-tracker-Don-t-leak-window-cursor-on-exit.patch
-wayland-cursor-surface-Update-cursor-on-dispose.patch
+compositor-view-Chain-up-finalize.patch
 wayland-xdg-shell-Dismiss-instead-of-destroy-invalid-popu.patch
+wayland-outputs-Fix-potential-crash-when-output-has-no-mo.patch
 tests-Break-up-stacking-installed-tests-into-more-smaller.patch
 tests-Use-a-more-interoperable-path-to-bash.patch
 meson-add-back-default_driver-option.patch
diff --git a/debian/patches/wayland-outputs-Fix-potential-crash-when-output-has-no-mo.patch b/debian/patches/wayland-outputs-Fix-potential-crash-when-output-has-no-mo.patch
new file mode 100644
index 000000000..afcde4c38
diff --git a/meson.build b/meson.build
index ba881c36f..f307a4736 100644
--- a/meson.build
+++ b/meson.build
@@ -1,5 +1,5 @@
 project('mutter', 'c',
-  version: '43.4',
+  version: '43.5',
   meson_version: '>= 0.55.0',
   license: 'GPLv2+'
 )
diff --git a/src/backends/meta-screen-cast-window-stream.c b/src/backends/meta-screen-cast-window-stream.c
index 6f42a446e..d678d4f61 100644
--- a/src/backends/meta-screen-cast-window-stream.c
+++ b/src/backends/meta-screen-cast-window-stream.c
@@ -197,6 +197,16 @@ meta_screen_cast_window_stream_finalize (GObject *object)
 {
   MetaScreenCastWindowStream *window_stream =
     META_SCREEN_CAST_WINDOW_STREAM (object);
+  MetaWindowActor *window_actor;
+
+  window_actor = meta_window_actor_from_window (window_stream->window);
+  if (window_actor)
+    {
+      MetaScreenCastWindow *screen_cast_window;
+
+      screen_cast_window = META_SCREEN_CAST_WINDOW (window_actor);
+      meta_screen_cast_window_dec_usage (screen_cast_window);
+    }
 
   g_clear_signal_handler (&window_stream->window_unmanaged_handler_id,
                           window_stream->window);
@@ -212,6 +222,8 @@ meta_screen_cast_window_stream_initable_init (GInitable     *initable,
   MetaScreenCastWindowStream *window_stream =
     META_SCREEN_CAST_WINDOW_STREAM (initable);
   MetaWindow *window = window_stream->window;
+  MetaScreenCastWindow *screen_cast_window =
+    META_SCREEN_CAST_WINDOW (meta_window_actor_from_window (window));
   MetaLogicalMonitor *logical_monitor;
   int scale;
 
@@ -242,6 +254,8 @@ meta_screen_cast_window_stream_initable_init (GInitable     *initable,
   window_stream->stream_width = logical_monitor->rect.width * scale;
   window_stream->stream_height = logical_monitor->rect.height * scale;
 
+  meta_screen_cast_window_inc_usage (screen_cast_window);
+
   return initable_parent_iface->init (initable, cancellable, error);
 }
 
diff --git a/src/backends/meta-screen-cast-window.c b/src/backends/meta-screen-cast-window.c
index b9c0df867..b36f9e16f 100644
--- a/src/backends/meta-screen-cast-window.c
+++ b/src/backends/meta-screen-cast-window.c
@@ -99,3 +99,15 @@ meta_screen_cast_window_has_damage (MetaScreenCastWindow *screen_cast_window)
 
   return iface->has_damage (screen_cast_window);
 }
+
+void
+meta_screen_cast_window_inc_usage (MetaScreenCastWindow *screen_cast_window)
+{
+  META_SCREEN_CAST_WINDOW_GET_IFACE (screen_cast_window)->inc_usage (screen_cast_window);
+}
+
+void
+meta_screen_cast_window_dec_usage (MetaScreenCastWindow *screen_cast_window)
+{
+  META_SCREEN_CAST_WINDOW_GET_IFACE (screen_cast_window)->dec_usage (screen_cast_window);
+}
diff --git a/src/backends/meta-screen-cast-window.h b/src/backends/meta-screen-cast-window.h
index d170d92ae..a2cc4cd40 100644
--- a/src/backends/meta-screen-cast-window.h
+++ b/src/backends/meta-screen-cast-window.h
@@ -62,6 +62,9 @@ struct _MetaScreenCastWindowInterface
                                    CoglFramebuffer      *framebuffer);
 
   gboolean (*has_damage) (MetaScreenCastWindow *screen_cast_window);
+
+  void (*inc_usage) (MetaScreenCastWindow *screen_cast_window);
+  void (*dec_usage) (MetaScreenCastWindow *screen_cast_window);
 };
 
 void meta_screen_cast_window_get_buffer_bounds (MetaScreenCastWindow *screen_cast_window,
@@ -90,6 +93,9 @@ gboolean meta_screen_cast_window_blit_to_framebuffer (MetaScreenCastWindow *scre
 
 gboolean meta_screen_cast_window_has_damage (MetaScreenCastWindow *screen_cast_window);
 
+void meta_screen_cast_window_inc_usage (MetaScreenCastWindow *screen_cast_window);
+void meta_screen_cast_window_dec_usage (MetaScreenCastWindow *screen_cast_window);
+
 G_END_DECLS
 
 #endif /* META_SCREEN_CAST_WINDOW_H */
diff --git a/src/compositor/meta-compositor-view.c b/src/compositor/meta-compositor-view.c
index b95cec7e8..6ce622424 100644
--- a/src/compositor/meta-compositor-view.c
+++ b/src/compositor/meta-compositor-view.c
@@ -170,6 +170,8 @@ meta_compositor_view_finalize (GObject *object)
     meta_compositor_view_get_instance_private (compositor_view);
 
   g_clear_weak_pointer (&priv->top_window_actor);
+
+  G_OBJECT_CLASS (meta_compositor_view_parent_class)->finalize (object);
 }
 
 static void
diff --git a/src/compositor/meta-surface-actor-wayland.c b/src/compositor/meta-surface-actor-wayland.c
index b8d354627..a9e5ea3d9 100644
--- a/src/compositor/meta-surface-actor-wayland.c
+++ b/src/compositor/meta-surface-actor-wayland.c
@@ -30,7 +30,9 @@
 
 #include "backends/meta-backend-private.h"
 #include "backends/meta-logical-monitor.h"
+#include "backends/meta-screen-cast-window.h"
 #include "compositor/meta-shaped-texture-private.h"
+#include "compositor/meta-window-actor-private.h"
 #include "compositor/region-utils.h"
 #include "wayland/meta-wayland-buffer.h"
 #include "wayland/meta-wayland-private.h"
@@ -74,15 +76,19 @@ meta_surface_actor_wayland_is_view_primary (MetaSurfaceActor *actor,
   ClutterStageView *current_primary_view = NULL;
   float highest_refresh_rate = 0.f;
   float biggest_unobscurred_fraction = 0.f;
+  MetaWindowActor *window_actor;
+  gboolean is_streaming = FALSE;
   GList *l;
 
-  if (!clutter_actor_is_effectively_on_stage_view (CLUTTER_ACTOR (actor),
-                                                   stage_view))
-    return FALSE;
+  window_actor = meta_window_actor_from_actor (CLUTTER_ACTOR (actor));
+  if (window_actor)
+    is_streaming = meta_window_actor_is_streaming (window_actor);
 
-  if (clutter_actor_has_mapped_clones (CLUTTER_ACTOR (actor)))
+  if (clutter_actor_has_mapped_clones (CLUTTER_ACTOR (actor)) || is_streaming)
     {
       ClutterStage *stage;
+      ClutterStageView *fallback_view = NULL;
+      float fallback_refresh_rate = 0.0;
 
       stage = CLUTTER_STAGE (clutter_actor_get_stage (CLUTTER_ACTOR (actor)));
       for (l = clutter_stage_peek_stage_views (stage); l; l = l->next)
@@ -90,28 +96,42 @@ meta_surface_actor_wayland_is_view_primary (MetaSurfaceActor *actor,
           ClutterStageView *view = l->data;
           float refresh_rate;
 
-          if (!clutter_actor_is_effectively_on_stage_view (CLUTTER_ACTOR (actor),
-                                                           view))
-            continue;
-
           refresh_rate = clutter_stage_view_get_refresh_rate (view);
-          if (refresh_rate > highest_refresh_rate)
+
+          if (clutter_actor_is_effectively_on_stage_view (CLUTTER_ACTOR (actor),
+                                                          view))
             {
-              current_primary_view = view;
-              highest_refresh_rate = refresh_rate;
+              if (refresh_rate > highest_refresh_rate)
+                {
+                  current_primary_view = view;
+                  highest_refresh_rate = refresh_rate;
+                }
+            }
+          else
+            {
+              if (refresh_rate > fallback_refresh_rate)
+                {
+                  fallback_view = view;
+                  fallback_refresh_rate = refresh_rate;
+                }
             }
         }
 
-      return current_primary_view == stage_view;
+      if (current_primary_view)
+        return current_primary_view == stage_view;
+      else if (is_streaming)
+        return fallback_view == stage_view;
     }
 
   l = clutter_actor_peek_stage_views (CLUTTER_ACTOR (actor));
-  g_return_val_if_fail (l, FALSE);
+  if (!l)
+    return FALSE;
 
   if (!l->next)
     {
-      g_return_val_if_fail (l->data == stage_view, FALSE);
-      return !meta_surface_actor_is_obscured (actor);
+      return !meta_surface_actor_is_obscured_on_stage_view (actor,
+                                                            stage_view,
+                                                            NULL);
     }
 
   for (; l; l = l->next)
diff --git a/src/compositor/meta-window-actor-private.h b/src/compositor/meta-window-actor-private.h
index 477d0b3a5..c1f46d590 100644
--- a/src/compositor/meta-window-actor-private.h
+++ b/src/compositor/meta-window-actor-private.h
@@ -101,6 +101,8 @@ void meta_window_actor_set_geometry_scale (MetaWindowActor *window_actor,
 
 int meta_window_actor_get_geometry_scale (MetaWindowActor *window_actor);
 
+gboolean meta_window_actor_is_streaming (MetaWindowActor *window_actor);
+
 void meta_window_actor_notify_damaged (MetaWindowActor *window_actor);
 
 gboolean meta_window_actor_is_frozen (MetaWindowActor *self);
diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c
index 02e81f0aa..943343c14 100644
--- a/src/compositor/meta-window-actor.c
+++ b/src/compositor/meta-window-actor.c
@@ -70,6 +70,7 @@ typedef struct _MetaWindowActorPrivate
   gint              destroy_in_progress;
 
   guint             freeze_count;
+  guint             screen_cast_usage_count;
 
   guint		    visible                : 1;
   guint		    disposed               : 1;
@@ -1392,6 +1393,26 @@ meta_window_actor_has_damage (MetaScreenCastWindow *screen_cast_window)
   return clutter_actor_has_damage (CLUTTER_ACTOR (screen_cast_window));
 }
 
+static void
+meta_window_actor_inc_screen_cast_usage (MetaScreenCastWindow *screen_cast_window)
+{
+  MetaWindowActor *window_actor = META_WINDOW_ACTOR (screen_cast_window);
+  MetaWindowActorPrivate *priv =
+    meta_window_actor_get_instance_private (window_actor);
+
+  priv->screen_cast_usage_count++;
+}
+
+static void
+meta_window_actor_dec_screen_cast_usage (MetaScreenCastWindow *screen_cast_window)
+{
+  MetaWindowActor *window_actor = META_WINDOW_ACTOR (screen_cast_window);
+  MetaWindowActorPrivate *priv =
+    meta_window_actor_get_instance_private (window_actor);
+
+  priv->screen_cast_usage_count--;
+}
+
 static void
 screen_cast_window_iface_init (MetaScreenCastWindowInterface *iface)
 {
@@ -1401,6 +1422,17 @@ screen_cast_window_iface_init (MetaScreenCastWindowInterface *iface)
   iface->capture_into = meta_window_actor_capture_into;
   iface->blit_to_framebuffer = meta_window_actor_blit_to_framebuffer;
   iface->has_damage = meta_window_actor_has_damage;
+  iface->inc_usage = meta_window_actor_inc_screen_cast_usage;
+  iface->dec_usage = meta_window_actor_dec_screen_cast_usage;
+}
+
+gboolean
+meta_window_actor_is_streaming (MetaWindowActor *window_actor)
+{
+  MetaWindowActorPrivate *priv =
+    meta_window_actor_get_instance_private (window_actor);
+
+  return priv->screen_cast_usage_count > 0;
 }
 
 MetaWindowActor *
diff --git a/src/core/window-private.h b/src/core/window-private.h
index 2f3e1e6d4..188b21468 100644
--- a/src/core/window-private.h
+++ b/src/core/window-private.h
@@ -888,8 +888,6 @@ void meta_window_show_close_dialog (MetaWindow *window);
 void meta_window_hide_close_dialog (MetaWindow *window);
 void meta_window_ensure_close_dialog_timeout (MetaWindow *window);
 
-gboolean meta_window_has_pointer (MetaWindow *window);
-
 void meta_window_emit_size_changed (MetaWindow *window);
 
 MetaPlacementRule *meta_window_get_placement_rule (MetaWindow *window);
diff --git a/src/meta/window.h b/src/meta/window.h
index d5d07a061..d4ba4966b 100644
--- a/src/meta/window.h
+++ b/src/meta/window.h
@@ -453,4 +453,7 @@ uint64_t meta_window_get_id (MetaWindow *window);
 META_EXPORT
 MetaWindowClientType meta_window_get_client_type (MetaWindow *window);
 
+META_EXPORT
+gboolean meta_window_has_pointer (MetaWindow *window);
+
 #endif
diff --git a/src/wayland/meta-wayland-actor-surface.c b/src/wayland/meta-wayland-actor-surface.c
index 2b76d943a..ca4b0d7c8 100644
--- a/src/wayland/meta-wayland-actor-surface.c
+++ b/src/wayland/meta-wayland-actor-surface.c
@@ -300,19 +300,14 @@ meta_wayland_actor_surface_apply_state (MetaWaylandSurfaceRole  *surface_role,
   MetaWaylandActorSurfacePrivate *priv =
     meta_wayland_actor_surface_get_instance_private (actor_surface);
 
-  if (!wl_list_empty (&pending->frame_callback_list) &&
-      priv->actor &&
-      !meta_surface_actor_is_obscured (priv->actor))
+  if (priv->actor && !wl_list_empty (&pending->frame_callback_list))
     {
-      GList *l;
+      ClutterStage *stage;
 
-      for (l = clutter_actor_peek_stage_views (CLUTTER_ACTOR (priv->actor)); l;
-           l = l->next)
-        {
-          ClutterStageView *view = l->data;
-
-          clutter_stage_view_schedule_update (view);
-        }
+      stage =
+        CLUTTER_STAGE (clutter_actor_get_stage (CLUTTER_ACTOR (priv->actor)));
+      if (stage)
+        clutter_stage_schedule_update (stage);
     }
 
   meta_wayland_actor_surface_queue_frame_callbacks (actor_surface, pending);
diff --git a/src/wayland/meta-wayland-outputs.c b/src/wayland/meta-wayland-outputs.c
index bdce99c6c..3c0861622 100644
--- a/src/wayland/meta-wayland-outputs.c
+++ b/src/wayland/meta-wayland-outputs.c
@@ -299,7 +299,12 @@ bind_output (struct wl_client *client,
 
   monitor = wayland_output->monitor;
   if (!monitor)
-    return;
+    {
+      wl_resource_set_implementation (resource,
+                                      &meta_wl_output_interface,
+                                      NULL, NULL);
+      return;
+    }
 
   wayland_output->resources = g_list_prepend (wayland_output->resources,
                                               resource);

Reply via email to