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

Bug#1036856: bookworm-pu: package mutter/43.6-1~deb12u1



Control: retitle -1 bookworm-pu: package mutter/43.6-1~deb12u1

On Sun, 28 May 2023 at 00:15:26 +0100, Simon McVittie wrote:
> The mutter 43.5 release from GNOME upstream seems like something we should
> have in a bookworm update.

So does the 43.6 release.

[ Reason ]
New upstream stable release

[ Impact ]
If not accepted, our default desktop will have several known bugs including
a crash during suspend/resume under some circumstances, and selectively
recording/screencasting a window that is not visible on a display not being
reliable. Additionally, this update is a prerequisite for a bug fix in
gnome-shell which I would also like to get fixed in bookworm (separate
bookworm-pu request, #1036858).

[ Tests ]
Manual testing: I'm running this version on my main laptop, and I'll
upload to unstable as soon as bookworm has been released.

Automated testing: mutter's test-suite still passes at build-time and in
autopkgtest.

[ Risks ]
There's the potential for regressions of similar magnitude to what we're
fixing. GNOME is our default desktop, so any regressions will be highly
visible.

[ Checklist ]
  [x] *all* changes are documented in the d/changelog
  [x] I reviewed all changes and I approve them
  [x] attach debdiff against the package in bookworm
  [ ] the issue is verified as fixed in unstable
      - intentionally not done yet, due to full freeze

[ Changes ]
src/backends/meta-screen-cast-window-stream.c,
src/backends/meta-screen-cast-window.c,
src/compositor/meta-surface-actor-wayland.c,
src/compositor/meta-window-actor.c: make sure that if a window is being
recorded or screencasted, it gets updated at the refresh rate of at least
some arbitrary display, even if it's not actually visible on any display
(for example because it's obscured by a window in front).

src/backends/native/meta-kms-impl-device-dummy.c:
don't crash on trying to blank the screen when run "headless" by
gnome-remote-desktop

src/wayland/meta-wayland-actor-surface.c: consider updating windows even if
they're fully obscured, to make sure that single-window
recording/screencasting works as intended, at the cost of not optimizing
away as many non-user-visible window updates.

src/compositor/meta-compositor-view.c: simple change to fix a resource leak
by calling the parent class's destructor correctly

src/wayland/meta-wayland-outputs.c: backported patch from version 44
(not part of 43.x upstream) to avoid a known source of crashes during
suspend/resume, which might resolve Debian bug reports #1010478 and/or
#1036268

src/core/window-private.h, src/meta/window.h, debian/libmutter-11-0.symbols:
export a symbol needed by GNOME Shell 43.5 for a screenshot bug fix there,
already present in 44.1 in experimental

[ Other info ]
I have not uploaded to unstable due to the full freeze, and I can't
upload to experimental because GNOME 44 is already there.
git diff patch-queue/43.4.. | filterdiff -p1 -x'debian/patches/*.patch' -x'po/*.po'

diff --git a/NEWS b/NEWS
index 65e5d1cf89..410519419e 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,24 @@
+43.6
+====
+* Fix popup issues [Jonas; !2940]
+* Plugged leak [Jonas; !2991]
+* Fixed crash [Jonas; !3037]
+
+Contributors:
+  Jonas Ådahl
+
+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 d7daed1235..5ec723d601 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,24 @@
+mutter (43.6-1) UNRELEASED; urgency=medium
+
+  * New upstream stable release 43.5
+    - 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
+  * New upstream stable release 43.6
+    - Fix a resource leak when a compositor view is destroyed (mutter!2991)
+    - Fix a crash when headless gdm greeter via gnome-remote-desktop
+      attempts to blank the screen (mutter#2841)
+  * d/patches: Drop patches that were applied upstream
+  * 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 on
+    some systems (mutter#2570, Closes: #1036268)
+
+ -- Simon McVittie <smcv@debian.org>  Tue, 06 Jun 2023 18:33:18 +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 1128f2ab36..f3b181d85b 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/series b/debian/patches/series
index 8be32b377a..baff484c1d 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -1,9 +1,4 @@
-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
-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 0000000000..afcde4c388
diff --git a/meson.build b/meson.build
index ba881c36f1..dc13a1172c 100644
--- a/meson.build
+++ b/meson.build
@@ -1,5 +1,5 @@
 project('mutter', 'c',
-  version: '43.4',
+  version: '43.6',
   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 6f42a446e8..d678d4f613 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 b9c0df867e..b36f9e16fe 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 d170d92ae7..a2cc4cd40f 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/backends/native/meta-kms-impl-device-dummy.c b/src/backends/native/meta-kms-impl-device-dummy.c
index 57fd6de255..f891b461db 100644
--- a/src/backends/native/meta-kms-impl-device-dummy.c
+++ b/src/backends/native/meta-kms-impl-device-dummy.c
@@ -45,6 +45,11 @@ meta_kms_impl_device_dummy_discard_pending_page_flips (MetaKmsImplDevice *impl_d
 {
 }
 
+static void
+meta_kms_impl_device_dummy_disable (MetaKmsImplDevice *impl_device)
+{
+}
+
 static MetaDeviceFile *
 meta_kms_impl_device_dummy_open_device_file (MetaKmsImplDevice  *impl_device,
                                              const char         *path,
@@ -101,4 +106,6 @@ meta_kms_impl_device_dummy_class_init (MetaKmsImplDeviceDummyClass *klass)
     meta_kms_impl_device_dummy_open_device_file;
   impl_device_class->discard_pending_page_flips =
     meta_kms_impl_device_dummy_discard_pending_page_flips;
+  impl_device_class->disable =
+    meta_kms_impl_device_dummy_disable;
 }
diff --git a/src/compositor/meta-compositor-view.c b/src/compositor/meta-compositor-view.c
index b95cec7e87..6ce622424c 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 b8d3546273..a9e5ea3d96 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 477d0b3a5b..c1f46d590d 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 02e81f0aac..943343c14f 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 2f3e1e6d45..188b21468a 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 d5d07a061e..d4ba4966b4 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 2b76d943a5..ca4b0d7c8b 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 bdce99c6c7..3c08616222 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 to: