Package: release.debian.org Severity: normal User: release.debian....@packages.debian.org Usertags: unblock X-Debbugs-Cc: mut...@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 <s...@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, ®istry_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;