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

Bug#1034681: marked as done (unblock: mutter/43.4-2)



Your message dated Sat, 22 Apr 2023 09:12:54 +0000
with message-id <E1pq9Ic-008vHZ-N7@respighi.debian.org>
and subject line unblock mutter
has caused the Debian Bug report #1034681,
regarding unblock: mutter/43.4-2
to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what this
message is talking about, this may indicate a serious mail system
misconfiguration somewhere. Please contact owner@bugs.debian.org
immediately.)


-- 
1034681: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1034681
Debian Bug Tracking System
Contact owner@bugs.debian.org with problems
--- Begin Message ---
Package: release.debian.org
Severity: normal
User: release.debian.org@packages.debian.org
Usertags: unblock
X-Debbugs-Cc: mutter@packages.debian.org
Control: affects -1 + src:mutter

Please unblock package mutter

[ Reason ]
Targeted fixes from upstream for several crashes

[ Impact ]
If not unblocked, our default desktop will have various easily fixable
crashes, one of which has been reported as RC (#1033484).

[ Tests ]
I tested #1033484 manually: there is a reliable
reproducer for what appears to be the same issue in
https://gitlab.gnome.org/GNOME/mutter/-/issues/2563#note_1723575, and it
crashed my gnome-shell with libmutter 43.4-1, but no longer does with
libmutter 43.4-2.

Upstream added an automated test (build-time test + autopkgtest) for
the crash fixed by mutter!2969, which passes.

The crash with experimental's glib2.0 (gnome-shell#6552, fixed by
mutter!2955) does not have explicit test coverage, but it seemed better
to have it than not.

[ Risks ]
The fixes are narrowly-targeted and the majority of the diffstat is unit
test coverage.

[ 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 testing

unblock mutter/43.4-2
debdiff *.dsc | filterdiff -p1 -x'debian/patches/*.patch'

diffstat for mutter-43.4 mutter-43.4

 clutter/clutter/clutter-actor.c                                                |    9 
 debian/changelog                                                               |   20 
 debian/libmutter-11-0.symbols                                                  |    3 
 debian/patches/clutter-actor-Get-next-action-from-list-before-handling-c.patch |   51 
 debian/patches/cursor-tracker-Don-t-leak-window-cursor-on-exit.patch           |   22 
 debian/patches/series                                                          |    4 
 debian/patches/wayland-cursor-surface-Update-cursor-on-dispose.patch           |  701 ++++++++++
 debian/patches/wayland-xdg-shell-Dismiss-instead-of-destroy-invalid-popu.patch |   28 
 meson.build                                                                    |    1 
 src/backends/meta-backend-private.h                                            |    1 
 src/backends/meta-cursor-renderer.h                                            |    2 
 src/backends/meta-cursor-tracker.c                                             |    1 
 src/tests/meson.build                                                          |    8 
 src/tests/monitor-configs/kms-cursor-hotplug-off.xml                           |   30 
 src/tests/monitor-configs/kms-cursor-hotplug-on.xml                            |   40 
 src/tests/native-kms-cursor-hotplug.c                                          |  165 ++
 src/tests/wayland-test-clients/kms-cursor-hotplug-helper.c                     |  286 ++++
 src/tests/wayland-test-clients/meson.build                                     |    6 
 src/wayland/meta-cursor-sprite-wayland.h                                       |    1 
 src/wayland/meta-wayland-cursor-surface.c                                      |    4 
 src/wayland/meta-wayland-xdg-shell.c                                           |    2 
 21 files changed, 1380 insertions(+), 5 deletions(-)

diff -Nru mutter-43.4/clutter/clutter/clutter-actor.c mutter-43.4/clutter/clutter/clutter-actor.c
--- mutter-43.4/clutter/clutter/clutter-actor.c	2023-03-19 22:26:48.000000000 +0000
+++ mutter-43.4/clutter/clutter/clutter-actor.c	2023-04-21 15:14:45.000000000 +0100
@@ -11972,20 +11972,21 @@
                            ClutterEventPhase   phase)
 {
   ClutterActorPrivate *priv;
-  const GList *actions, *l;
+  const GList *l;
   gboolean retval = CLUTTER_EVENT_PROPAGATE;
 
   priv = self->priv;
   if (!priv->actions)
     return CLUTTER_EVENT_PROPAGATE;
 
-  actions = _clutter_meta_group_peek_metas (priv->actions);
-
-  for (l = actions; l; l = l->next)
+  l = _clutter_meta_group_peek_metas (priv->actions);
+  while (l)
     {
       ClutterAction *action = l->data;
       ClutterEventPhase action_phase;
 
+      l = l->next;
+
       action_phase = clutter_action_get_phase (action);
 
       if (action_phase == phase)
diff -Nru mutter-43.4/debian/changelog mutter-43.4/debian/changelog
--- mutter-43.4/debian/changelog	2023-04-10 14:07:33.000000000 +0100
+++ mutter-43.4/debian/changelog	2023-04-21 10:10:24.000000000 +0100
@@ -1,3 +1,23 @@
+mutter (43.4-2) unstable; urgency=medium
+
+  * Team upload
+  * d/patches: Update to upstream gnome-43 branch commit 43.4-5-gc35e9f8c0
+    - d/p/clutter-actor-Get-next-action-from-list-before-handling-c.patch:
+      Fix a use-after-free that was always a problem in theory, but causes
+      crashes in practice with GLib 2.76.x (mutter!2955, gnome-shell#6552)
+    - d/p/cursor-tracker-Don-t-leak-window-cursor-on-exit.patch:
+      Fix a minor memory leak (mutter!2969)
+    - d/p/wayland-cursor-surface-Update-cursor-on-dispose.patch:
+      Fix a crash in rare situations involving Wayland cursor changes,
+      and add test coverage (mutter!2969)
+  * d/libmutter-11-0.symbols: Add new private symbols used by tests
+    for the above changes
+  * d/p/wayland-xdg-shell-Dismiss-instead-of-destroy-invalid-popu.patch:
+    Backport a fix from upstream 44.x branch to fix popup-related crashes
+    (mutter#2728, mutter!2940, Closes: #1033484)
+
+ -- Simon McVittie <smcv@debian.org>  Fri, 21 Apr 2023 10:10:24 +0100
+
 mutter (43.4-1) unstable; urgency=medium
 
   * Team upload
diff -Nru mutter-43.4/debian/libmutter-11-0.symbols mutter-43.4/debian/libmutter-11-0.symbols
--- mutter-43.4/debian/libmutter-11-0.symbols	2023-04-10 14:07:33.000000000 +0100
+++ mutter-43.4/debian/libmutter-11-0.symbols	2023-04-21 10:10:24.000000000 +0100
@@ -16,6 +16,7 @@
  meta_backend_get_context@Base 43.0
  meta_backend_get_core_idle_monitor@Base 43.0
  meta_backend_get_current_logical_monitor@Base 43.0
+ meta_backend_get_cursor_renderer@Base 43.4-2~
  meta_backend_get_cursor_tracker@Base 43.0
  meta_backend_get_default_seat@Base 43.0
  meta_backend_get_dnd@Base 43.0
@@ -159,6 +160,8 @@
  meta_crtc_unassign_output@Base 43.0
  meta_crtc_unset_config@Base 43.0
  meta_cursor_get_type@Base 43.0
+ meta_cursor_renderer_get_cursor@Base 43.4-2~
+ meta_cursor_sprite_wayland_get_type@Base 43.4-2~
  meta_cursor_tracker_get_for_display@Base 43.0
  meta_cursor_tracker_get_hot@Base 43.0
  meta_cursor_tracker_get_pointer@Base 43.0
diff -Nru mutter-43.4/debian/patches/series mutter-43.4/debian/patches/series
--- mutter-43.4/debian/patches/series	2023-04-10 14:07:33.000000000 +0100
+++ mutter-43.4/debian/patches/series	2023-04-21 10:10:24.000000000 +0100
@@ -1,5 +1,9 @@
 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
 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 -Nru mutter-43.4/meson.build mutter-43.4/meson.build
--- mutter-43.4/meson.build	2023-04-21 15:14:44.000000000 +0100
+++ mutter-43.4/meson.build	2023-04-21 15:14:45.000000000 +0100
@@ -207,6 +207,7 @@
 if have_wayland
   wayland_server_dep = dependency('wayland-server', version: wayland_server_req)
   wayland_client_dep = dependency('wayland-client', version: wayland_server_req)
+  wayland_cursor_dep = dependency('wayland-cursor')
   wayland_protocols_dep = dependency('wayland-protocols',
                                      version: wayland_protocols_req)
   wayland_egl_dep = dependency('wayland-egl')
diff -Nru mutter-43.4/src/backends/meta-backend-private.h mutter-43.4/src/backends/meta-backend-private.h
--- mutter-43.4/src/backends/meta-backend-private.h	2023-03-19 22:26:48.000000000 +0000
+++ mutter-43.4/src/backends/meta-backend-private.h	2023-04-21 15:14:45.000000000 +0100
@@ -135,6 +135,7 @@
 MetaCursorTracker * meta_backend_get_cursor_tracker (MetaBackend *backend);
 MetaCursorRenderer * meta_backend_get_cursor_renderer_for_device (MetaBackend        *backend,
                                                                   ClutterInputDevice *device);
+META_EXPORT_TEST
 MetaCursorRenderer * meta_backend_get_cursor_renderer (MetaBackend *backend);
 META_EXPORT_TEST
 MetaRenderer * meta_backend_get_renderer (MetaBackend *backend);
diff -Nru mutter-43.4/src/backends/meta-cursor-renderer.h mutter-43.4/src/backends/meta-cursor-renderer.h
--- mutter-43.4/src/backends/meta-cursor-renderer.h	2023-03-19 22:26:48.000000000 +0000
+++ mutter-43.4/src/backends/meta-cursor-renderer.h	2023-04-21 15:14:45.000000000 +0100
@@ -29,6 +29,7 @@
 
 #include "backends/meta-backend-types.h"
 #include "backends/meta-cursor.h"
+#include "core/util-private.h"
 
 #define META_TYPE_HW_CURSOR_INHIBITOR (meta_hw_cursor_inhibitor_get_type ())
 G_DECLARE_INTERFACE (MetaHwCursorInhibitor, meta_hw_cursor_inhibitor,
@@ -64,6 +65,7 @@
 void meta_cursor_renderer_update_position (MetaCursorRenderer *renderer);
 void meta_cursor_renderer_force_update (MetaCursorRenderer *renderer);
 
+META_EXPORT_TEST
 MetaCursorSprite * meta_cursor_renderer_get_cursor (MetaCursorRenderer *renderer);
 
 graphene_rect_t meta_cursor_renderer_calculate_rect (MetaCursorRenderer *renderer,
diff -Nru mutter-43.4/src/backends/meta-cursor-tracker.c mutter-43.4/src/backends/meta-cursor-tracker.c
--- mutter-43.4/src/backends/meta-cursor-tracker.c	2023-03-19 22:26:48.000000000 +0000
+++ mutter-43.4/src/backends/meta-cursor-tracker.c	2023-04-21 15:14:45.000000000 +0100
@@ -262,6 +262,7 @@
 
   g_clear_object (&priv->effective_cursor);
   g_clear_object (&priv->displayed_cursor);
+  g_clear_object (&priv->window_cursor);
   g_clear_object (&priv->root_cursor);
 
   G_OBJECT_CLASS (meta_cursor_tracker_parent_class)->dispose (object);
diff -Nru mutter-43.4/src/tests/meson.build mutter-43.4/src/tests/meson.build
--- mutter-43.4/src/tests/meson.build	2023-04-21 15:14:44.000000000 +0100
+++ mutter-43.4/src/tests/meson.build	2023-04-21 15:14:45.000000000 +0100
@@ -353,6 +353,14 @@
       ],
       'variants': kms_test_variants,
     },
+    {
+      'name': 'kms-cursor-hotplug',
+      'suite': 'backends/native',
+      'sources': [
+        'native-kms-cursor-hotplug.c',
+        wayland_test_utils,
+      ],
+    },
   ]
 
   privileged_test_cases += kms_test_cases
diff -Nru mutter-43.4/src/tests/monitor-configs/kms-cursor-hotplug-off.xml mutter-43.4/src/tests/monitor-configs/kms-cursor-hotplug-off.xml
--- mutter-43.4/src/tests/monitor-configs/kms-cursor-hotplug-off.xml	1970-01-01 01:00:00.000000000 +0100
+++ mutter-43.4/src/tests/monitor-configs/kms-cursor-hotplug-off.xml	2023-04-21 15:14:45.000000000 +0100
@@ -0,0 +1,30 @@
+<monitors version="2">
+  <configuration>
+    <logicalmonitor>
+      <x>0</x>
+      <y>0</y>
+      <primary>yes</primary>
+      <monitor>
+	<monitorspec>
+	  <connector>Meta-0</connector>
+	  <vendor>MetaTestVendor</vendor>
+	  <product>MetaVirtualMonitor</product>
+	  <serial>0x1234</serial>
+	</monitorspec>
+	<mode>
+	  <width>100</width>
+	  <height>100</height>
+	  <rate>60</rate>
+	</mode>
+      </monitor>
+    </logicalmonitor>
+    <disabled>
+      <monitorspec>
+	<connector>Virtual-1</connector>
+	<vendor>unknown</vendor>
+	<product>unknown</product>
+	<serial>unknown</serial>
+      </monitorspec>
+    </disabled>
+  </configuration>
+</monitors>
diff -Nru mutter-43.4/src/tests/monitor-configs/kms-cursor-hotplug-on.xml mutter-43.4/src/tests/monitor-configs/kms-cursor-hotplug-on.xml
--- mutter-43.4/src/tests/monitor-configs/kms-cursor-hotplug-on.xml	1970-01-01 01:00:00.000000000 +0100
+++ mutter-43.4/src/tests/monitor-configs/kms-cursor-hotplug-on.xml	2023-04-21 15:14:45.000000000 +0100
@@ -0,0 +1,40 @@
+<monitors version="2">
+  <configuration>
+    <logicalmonitor>
+      <x>0</x>
+      <y>0</y>
+      <primary>yes</primary>
+      <monitor>
+	<monitorspec>
+	  <connector>Virtual-1</connector>
+	  <vendor>unknown</vendor>
+	  <product>unknown</product>
+	  <serial>unknown</serial>
+	</monitorspec>
+	<mode>
+	  <width>1024</width>
+	  <height>768</height>
+	  <rate>60.003841</rate>
+	</mode>
+      </monitor>
+    </logicalmonitor>
+    <logicalmonitor>
+      <x>1024</x>
+      <y>0</y>
+      <primary>no</primary>
+      <monitor>
+	<monitorspec>
+	  <connector>Meta-0</connector>
+	  <vendor>MetaTestVendor</vendor>
+	  <product>MetaVirtualMonitor</product>
+	  <serial>0x1234</serial>
+	</monitorspec>
+	<mode>
+	  <width>100</width>
+	  <height>100</height>
+	  <rate>60</rate>
+	</mode>
+      </monitor>
+    </logicalmonitor>
+  </configuration>
+</monitors>
diff -Nru mutter-43.4/src/tests/native-kms-cursor-hotplug.c mutter-43.4/src/tests/native-kms-cursor-hotplug.c
--- mutter-43.4/src/tests/native-kms-cursor-hotplug.c	1970-01-01 01:00:00.000000000 +0100
+++ mutter-43.4/src/tests/native-kms-cursor-hotplug.c	2023-04-21 15:14:45.000000000 +0100
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2022 Red Hat Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ *
+ */
+
+#include "config.h"
+
+#include "backends/meta-monitor-config-manager.h"
+#include "backends/meta-virtual-monitor.h"
+#include "core/window-private.h"
+#include "meta-test/meta-context-test.h"
+#include "meta/meta-backend.h"
+#include "meta/meta-cursor-tracker.h"
+#include "tests/meta-test-utils.h"
+#include "tests/meta-wayland-test-driver.h"
+#include "tests/meta-wayland-test-utils.h"
+#include "tests/native-screen-cast.h"
+#include "tests/native-virtual-monitor.h"
+#include "wayland/meta-cursor-sprite-wayland.h"
+#include "wayland/meta-wayland-private.h"
+#include "wayland/meta-wayland-seat.h"
+
+static MetaContext *test_context;
+
+static void
+meta_test_cursor_hotplug (void)
+{
+  MetaBackend *backend = meta_context_get_backend (test_context);
+  MetaMonitorManager *monitor_manager =
+    meta_backend_get_monitor_manager (backend);
+  MetaCursorRenderer *cursor_renderer = meta_backend_get_cursor_renderer (backend);
+  MetaWaylandCompositor *wayland_compositor =
+    meta_context_get_wayland_compositor (test_context);
+  MetaWaylandSeat *wayland_seat = wayland_compositor->seat;
+  g_autoptr (MetaWaylandTestDriver) test_driver = NULL;
+  MetaCursorSprite *cursor_sprite;
+  g_autoptr (MetaVirtualMonitorInfo) monitor_info = NULL;
+  MetaVirtualMonitor *virtual_monitor;
+  ClutterSeat *seat;
+  g_autoptr (ClutterVirtualInputDevice) virtual_pointer = NULL;
+  MetaWaylandTestClient *test_client;
+  MetaWindow *window;
+  GError *error = NULL;
+
+  test_driver = meta_wayland_test_driver_new (wayland_compositor);
+
+  seat = meta_backend_get_default_seat (backend);
+  virtual_pointer = clutter_seat_create_virtual_device (seat,
+                                                        CLUTTER_POINTER_DEVICE);
+
+  meta_set_custom_monitor_config_full (backend, "kms-cursor-hotplug-off.xml",
+                                       META_MONITORS_CONFIG_FLAG_NONE);
+
+  monitor_info = meta_virtual_monitor_info_new (100, 100, 60.0,
+                                                "MetaTestVendor",
+                                                "MetaVirtualMonitor",
+                                                "0x1234");
+  virtual_monitor = meta_monitor_manager_create_virtual_monitor (monitor_manager,
+                                                                 monitor_info,
+                                                                 &error);
+  if (!virtual_monitor)
+    g_error ("Failed to create virtual monitor: %s", error->message);
+  meta_monitor_manager_reload (monitor_manager);
+
+  clutter_virtual_input_device_notify_absolute_motion (virtual_pointer,
+                                                       g_get_monotonic_time (),
+                                                       50, 50);
+
+  test_client = meta_wayland_test_client_new ("kms-cursor-hotplug-helper");
+  if (!test_client)
+    g_error ("Failed to launch test client: %s", error->message);
+
+  while (TRUE)
+    {
+      window = meta_find_window_from_title (test_context,
+                                            "kms-cursor-hotplug-helper");
+      if (window && window->visible_to_compositor)
+        break;
+      g_main_context_iteration (NULL, TRUE);
+    }
+
+  meta_window_move_frame (window, FALSE, 0, 0);
+  meta_wait_for_paint (test_context);
+
+  cursor_renderer = meta_backend_get_cursor_renderer (backend);
+
+  while (TRUE)
+    {
+      cursor_sprite = meta_cursor_renderer_get_cursor (cursor_renderer);
+      if (cursor_sprite)
+        break;
+      g_main_context_iteration (NULL, TRUE);
+    }
+  g_assert_true (META_IS_CURSOR_SPRITE_WAYLAND (cursor_sprite));
+
+  /*
+   * This tests a particular series of events:
+   *
+   *  1) Unplug the mouse
+   *  2) Client attaches a new cursor buffer
+   *  3) Client destroys cursor surface
+   *  4) Monitor hotplug
+   *
+   * This would cause a NULL pointer deference when getting the buffer from the
+   * cursor surface when trying to realize the hardware cursor buffer on the
+   * hotplugged monitor.
+   */
+
+  g_clear_object (&virtual_pointer);
+  while (!(wayland_seat->capabilities & WL_SEAT_CAPABILITY_POINTER))
+    g_main_context_iteration (NULL, TRUE);
+
+  meta_wayland_test_driver_emit_sync_event (test_driver, 0);
+  meta_wayland_test_driver_wait_for_sync_point (test_driver, 0);
+
+  meta_set_custom_monitor_config_full (backend, "kms-cursor-hotplug-on.xml",
+                                       META_MONITORS_CONFIG_FLAG_NONE);
+  meta_monitor_manager_reload (monitor_manager);
+  meta_wait_for_paint (test_context);
+
+  meta_wayland_test_driver_emit_sync_event (test_driver, 1);
+  meta_wayland_test_client_finish (test_client);
+}
+
+static void
+init_tests (void)
+{
+  g_test_add_func ("/wayland/cursor-hotplug",
+                   meta_test_cursor_hotplug);
+}
+
+int
+main (int    argc,
+      char **argv)
+{
+  g_autoptr (MetaContext) context = NULL;
+
+  context = meta_create_test_context (META_CONTEXT_TEST_TYPE_VKMS,
+                                      META_CONTEXT_TEST_FLAG_NO_X11 |
+                                      META_CONTEXT_TEST_FLAG_TEST_CLIENT);
+  g_assert (meta_context_configure (context, &argc, &argv, NULL));
+
+  test_context = context;
+
+  init_tests ();
+
+  return meta_context_test_run_tests (META_CONTEXT_TEST (context),
+                                      META_TEST_RUN_FLAG_NONE);
+}
+
diff -Nru mutter-43.4/src/tests/wayland-test-clients/kms-cursor-hotplug-helper.c mutter-43.4/src/tests/wayland-test-clients/kms-cursor-hotplug-helper.c
--- mutter-43.4/src/tests/wayland-test-clients/kms-cursor-hotplug-helper.c	1970-01-01 01:00:00.000000000 +0100
+++ mutter-43.4/src/tests/wayland-test-clients/kms-cursor-hotplug-helper.c	2023-04-21 15:14:45.000000000 +0100
@@ -0,0 +1,286 @@
+/*
+ * Copyright (C) 2023 Red Hat Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include <glib.h>
+#include <wayland-client.h>
+#include <wayland-cursor.h>
+
+#include "wayland-test-client-utils.h"
+
+static WaylandDisplay *display;
+
+static struct wl_registry *wl_registry;
+static struct wl_seat *wl_seat;
+static struct wl_pointer *wl_pointer;
+static uint32_t enter_serial;
+
+static struct wl_surface *surface;
+static struct xdg_surface *xdg_surface;
+static struct xdg_toplevel *xdg_toplevel;
+struct wl_surface *cursor_surface;
+struct wl_cursor_theme *cursor_theme;
+struct wl_cursor *cursor;
+struct wl_cursor *cursor2;
+
+static gboolean running;
+
+static void
+init_surface (void)
+{
+  xdg_toplevel_set_title (xdg_toplevel, "kms-cursor-hotplug-helper");
+  wl_surface_commit (surface);
+}
+
+static void
+draw_main (int width,
+           int height)
+{
+  draw_surface (display, surface, width, height, 0xff00ff00);
+}
+
+static void
+handle_xdg_toplevel_configure (void                *data,
+                               struct xdg_toplevel *xdg_toplevel,
+                               int32_t              width,
+                               int32_t              height,
+                               struct wl_array     *state)
+{
+}
+
+static void
+handle_xdg_toplevel_close (void                *data,
+                           struct xdg_toplevel *xdg_toplevel)
+{
+  g_assert_not_reached ();
+}
+
+static void
+handle_xdg_toplevel_configure_bounds (void                *data,
+                                      struct xdg_toplevel *xdg_toplevel,
+                                      int32_t              bounds_width,
+                                      int32_t              bounds_height)
+{
+}
+
+static const struct xdg_toplevel_listener xdg_toplevel_listener = {
+  handle_xdg_toplevel_configure,
+  handle_xdg_toplevel_close,
+  handle_xdg_toplevel_configure_bounds,
+};
+
+static void
+handle_xdg_surface_configure (void               *data,
+                              struct xdg_surface *xdg_surface,
+                              uint32_t            serial)
+{
+  draw_main (100, 100);
+  xdg_surface_ack_configure (xdg_surface, serial);
+  wl_surface_commit (surface);
+}
+
+static const struct xdg_surface_listener xdg_surface_listener = {
+  handle_xdg_surface_configure,
+};
+
+
+static void
+pointer_handle_enter (void              *data,
+                      struct wl_pointer *pointer,
+                      uint32_t           serial,
+                      struct wl_surface *surface,
+                      wl_fixed_t         sx,
+                      wl_fixed_t         sy)
+{
+  struct wl_buffer *buffer;
+  struct wl_cursor_image *image;
+
+  image = cursor->images[0];
+  buffer = wl_cursor_image_get_buffer (image);
+
+  enter_serial = serial;
+  wl_pointer_set_cursor (pointer, serial,
+                         cursor_surface,
+                         image->hotspot_x,
+                         image->hotspot_y);
+  wl_surface_attach (cursor_surface, buffer, 0, 0);
+  wl_surface_damage (cursor_surface, 0, 0,
+                     image->width, image->height);
+  wl_surface_commit (cursor_surface);
+}
+
+static void
+pointer_handle_leave (void              *data,
+                      struct wl_pointer *pointer,
+                      uint32_t           serial,
+                      struct wl_surface *surface)
+{
+}
+
+static void
+pointer_handle_motion (void              *data,
+                       struct wl_pointer *pointer,
+                       uint32_t           time,
+                       wl_fixed_t         sx,
+                       wl_fixed_t         sy)
+{
+}
+
+static void
+pointer_handle_button (void              *data,
+                       struct wl_pointer *pointer,
+                       uint32_t           serial,
+                       uint32_t           time,
+                       uint32_t           button,
+                       uint32_t           state)
+{
+}
+
+static void
+pointer_handle_axis (void              *data,
+                     struct wl_pointer *pointer,
+                     uint32_t           time,
+                     uint32_t           axis,
+                     wl_fixed_t         value)
+{
+}
+
+static const struct wl_pointer_listener pointer_listener = {
+  pointer_handle_enter,
+  pointer_handle_leave,
+  pointer_handle_motion,
+  pointer_handle_button,
+  pointer_handle_axis,
+};
+
+static void
+seat_handle_capabilities (void                    *data,
+                          struct wl_seat          *wl_seat,
+                          enum wl_seat_capability  caps)
+{
+  if (caps & WL_SEAT_CAPABILITY_POINTER)
+    {
+      wl_pointer = wl_seat_get_pointer (wl_seat);
+      wl_pointer_add_listener (wl_pointer, &pointer_listener, NULL);
+    }
+}
+
+static void
+seat_handle_name (void           *data,
+                  struct wl_seat *seat,
+                  const char     *name)
+{
+}
+
+static const struct wl_seat_listener seat_listener = {
+  seat_handle_capabilities,
+  seat_handle_name,
+};
+
+static void
+handle_registry_global (void               *data,
+                        struct wl_registry *registry,
+                        uint32_t            id,
+                        const char         *interface,
+                        uint32_t            version)
+{
+  if (strcmp (interface, "wl_seat") == 0)
+    {
+      wl_seat = wl_registry_bind (registry, id,
+                                  &wl_seat_interface,
+                                  1);
+      wl_seat_add_listener (wl_seat, &seat_listener, NULL);
+    }
+}
+
+static void
+handle_registry_global_remove (void               *data,
+                               struct wl_registry *registry,
+                               uint32_t            name)
+{
+}
+
+static const struct wl_registry_listener registry_listener = {
+  handle_registry_global,
+  handle_registry_global_remove
+};
+
+static void
+on_sync_event (WaylandDisplay *display,
+               uint32_t        serial)
+{
+  if (serial == 1)
+    {
+      running = FALSE;
+    }
+  else if (serial == 0)
+    {
+      struct wl_buffer *buffer;
+      struct wl_cursor_image *image;
+
+      image = cursor2->images[0];
+      buffer = wl_cursor_image_get_buffer (image);
+
+      wl_surface_attach (cursor_surface, buffer, 0, 0);
+      wl_surface_damage (cursor_surface, 0, 0,
+                         image->width, image->height);
+      wl_surface_commit (cursor_surface);
+
+      wl_surface_destroy (cursor_surface);
+
+      test_driver_sync_point (display->test_driver, 0, NULL);
+    }
+}
+
+int
+main (int    argc,
+      char **argv)
+{
+  display = wayland_display_new (WAYLAND_DISPLAY_CAPABILITY_TEST_DRIVER);
+  wl_registry = wl_display_get_registry (display->display);
+  wl_registry_add_listener (wl_registry, &registry_listener, display);
+  wl_display_roundtrip (display->display);
+
+  g_signal_connect (display, "sync-event", G_CALLBACK (on_sync_event), NULL);
+
+  surface = wl_compositor_create_surface (display->compositor);
+  xdg_surface = xdg_wm_base_get_xdg_surface (display->xdg_wm_base, surface);
+  xdg_surface_add_listener (xdg_surface, &xdg_surface_listener, NULL);
+  xdg_toplevel = xdg_surface_get_toplevel (xdg_surface);
+  xdg_toplevel_add_listener (xdg_toplevel, &xdg_toplevel_listener, NULL);
+
+  cursor_surface = wl_compositor_create_surface (display->compositor);
+  cursor_theme = wl_cursor_theme_load (NULL, 24, display->shm);
+  cursor = wl_cursor_theme_get_cursor (cursor_theme, "left_ptr");
+  cursor2 = wl_cursor_theme_get_cursor (cursor_theme, "right_ptr");
+  g_assert_nonnull (cursor);
+  g_assert_nonnull (cursor2);
+
+  init_surface ();
+  wl_surface_commit (surface);
+
+  running = TRUE;
+  while (running)
+    {
+      if (wl_display_dispatch (display->display) == -1)
+        return EXIT_FAILURE;
+    }
+
+  return EXIT_SUCCESS;
+}
+
diff -Nru mutter-43.4/src/tests/wayland-test-clients/meson.build mutter-43.4/src/tests/wayland-test-clients/meson.build
--- mutter-43.4/src/tests/wayland-test-clients/meson.build	2023-03-19 22:26:48.000000000 +0000
+++ mutter-43.4/src/tests/wayland-test-clients/meson.build	2023-04-21 15:14:45.000000000 +0100
@@ -80,6 +80,12 @@
     'name': 'fullscreen',
   },
   {
+    'name': 'kms-cursor-hotplug-helper',
+    'extra_deps': [
+      wayland_cursor_dep,
+    ],
+  },
+  {
     'name': 'dma-buf-scanout',
     'extra_deps': [
       libdrm_dep,
diff -Nru mutter-43.4/src/wayland/meta-cursor-sprite-wayland.h mutter-43.4/src/wayland/meta-cursor-sprite-wayland.h
--- mutter-43.4/src/wayland/meta-cursor-sprite-wayland.h	2023-03-19 22:26:48.000000000 +0000
+++ mutter-43.4/src/wayland/meta-cursor-sprite-wayland.h	2023-04-21 15:14:45.000000000 +0100
@@ -25,6 +25,7 @@
 #include "wayland/meta-wayland-surface.h"
 
 #define META_TYPE_CURSOR_SPRITE_WAYLAND meta_cursor_sprite_wayland_get_type ()
+META_EXPORT_TEST
 G_DECLARE_FINAL_TYPE (MetaCursorSpriteWayland, meta_cursor_sprite_wayland,
                       META, CURSOR_SPRITE_WAYLAND, MetaCursorSprite)
 
diff -Nru mutter-43.4/src/wayland/meta-wayland-cursor-surface.c mutter-43.4/src/wayland/meta-wayland-cursor-surface.c
--- mutter-43.4/src/wayland/meta-wayland-cursor-surface.c	2023-03-19 22:26:48.000000000 +0000
+++ mutter-43.4/src/wayland/meta-wayland-cursor-surface.c	2023-04-21 15:14:45.000000000 +0100
@@ -215,6 +215,8 @@
     meta_wayland_cursor_surface_get_instance_private (cursor_surface);
   MetaWaylandSurface *surface =
     meta_wayland_surface_role_get_surface (META_WAYLAND_SURFACE_ROLE (object));
+  MetaWaylandSeat *seat = surface->compositor->seat;
+  MetaWaylandPointer *pointer = seat->pointer;
   MetaWaylandFrameCallback *cb, *next;
 
   wl_list_for_each_safe (cb, next, &priv->frame_callbacks, link)
@@ -238,6 +240,8 @@
       g_clear_object (&priv->buffer);
     }
 
+  meta_wayland_pointer_update_cursor_surface (pointer);
+
   G_OBJECT_CLASS (meta_wayland_cursor_surface_parent_class)->dispose (object);
 }
 
diff -Nru mutter-43.4/src/wayland/meta-wayland-xdg-shell.c mutter-43.4/src/wayland/meta-wayland-xdg-shell.c
--- mutter-43.4/src/wayland/meta-wayland-xdg-shell.c	2023-03-19 22:26:48.000000000 +0000
+++ mutter-43.4/src/wayland/meta-wayland-xdg-shell.c	2023-04-21 15:14:45.000000000 +0100
@@ -1155,7 +1155,7 @@
           top_xdg_popup = meta_wayland_xdg_popup_from_surface (top_popup_surface);
 
           xdg_popup_send_popup_done (top_xdg_popup->resource);
-          meta_wayland_popup_destroy (top_xdg_popup->popup);
+          meta_wayland_popup_dismiss (top_xdg_popup->popup);
 
           if (top_xdg_popup == xdg_popup)
             break;

--- End Message ---
--- Begin Message ---
Unblocked.

--- End Message ---

Reply to: