Bug#1109275: unblock: mutter/48.4-2
On Mon, 14 Jul 2025 at 14:16:57 +0100, Simon McVittie wrote:
[x] attach debdiff against the package in testing
Now really attached.
smcv
diffstat for mutter-48.3.1 mutter-48.4
NEWS | 18 ++++++++
cogl/cogl/cogl-pipeline.c | 7 ++-
debian/changelog | 62 ++++++++++++++++++++++++++++
debian/control | 2
debian/gbp.conf | 4 -
debian/watch | 2
doc/reference/clutter/clutter.toml.in | 4 -
doc/reference/cogl/cogl.toml.in | 4 -
doc/reference/meta/meta.toml.in | 4 -
doc/reference/mtk/mtk.toml.in | 4 -
doc/website/index.html | 1
meson.build | 2
src/backends/native/meta-gpu-kms.c | 2
src/backends/native/meta-kms-impl-device.c | 10 ++++
src/backends/native/meta-kms.c | 2
src/backends/native/meta-onscreen-native.c | 2
src/backends/native/meta-output-kms.c | 11 ++++
src/backends/native/meta-output-kms.h | 2
src/backends/native/meta-seat-impl.c | 4 -
src/compositor/compositor-private.h | 6 +-
src/compositor/compositor.c | 10 ++--
src/core/bell.c | 64 ++++++++++++++++++++++++-----
src/core/display-private.h | 7 +--
src/core/meta-context-main.c | 2
src/core/window.c | 7 +++
src/tests/test-runner.c | 2
src/wayland/meta-wayland-data-device.c | 59 ++++----------------------
src/wayland/meta-wayland-data-source.c | 59 ++++++++++++++++++++++++++
src/wayland/meta-wayland-data-source.h | 3 +
src/wayland/meta-wayland-seat.c | 4 -
src/x11/meta-x11-display.c | 8 +++
31 files changed, 286 insertions(+), 92 deletions(-)
diff -Nru mutter-48.3.1/cogl/cogl/cogl-pipeline.c mutter-48.4/cogl/cogl/cogl-pipeline.c
--- mutter-48.3.1/cogl/cogl/cogl-pipeline.c 2025-06-02 23:01:18.000000000 +0100
+++ mutter-48.4/cogl/cogl/cogl-pipeline.c 2025-06-29 11:00:20.000000000 +0100
@@ -121,11 +121,14 @@
{
for (CoglPipeline *child = pipeline->first_child;
- child != NULL;
- child = child->next_sibling)
+ child != NULL;)
{
+ CoglPipeline *next = child->next_sibling;
+
if (!callback (child, user_data))
break;
+
+ child = next;
}
}
diff -Nru mutter-48.3.1/debian/changelog mutter-48.4/debian/changelog
--- mutter-48.3.1/debian/changelog 2025-06-14 10:07:10.000000000 +0100
+++ mutter-48.4/debian/changelog 2025-07-13 12:27:01.000000000 +0100
@@ -1,3 +1,65 @@
+mutter (48.4-2) unstable; urgency=medium
+
+ * Team upload
+ * d/gbp.conf, d/control: Switch packaging branch for trixie
+ * Expand previous changelog entry to document all upstream changes
+ * Upload to unstable
+
+ -- Simon McVittie <smcv@debian.org> Sun, 13 Jul 2025 12:27:01 +0100
+
+mutter (48.4-1) experimental; urgency=medium
+
+ [ Jeremy Bícha ]
+ * New upstream bugfix release
+ - Unlink outputs from unused connectors in update_outputs, avoiding a
+ use-after-free when a monitor is disconnected
+ (mutter!4474 upstream)
+ - Fix a crash caused by a use-after-free when clearing many
+ accumulated notifications
+ (mutter#3970 upstream, LP: #2102063)
+ - Fix a non-reproducible crash caused by a use-after-free when dragging
+ an epiphany-browser tab to create a new window
+ (mutter#4157 upstream)
+ - Fix the logic for when to disable the --no-x11 option
+ (mutter!4485 upstream, not relevant to how we configure it in Debian)
+ - Rate-limit visual alerts to 2 per second, to comply with the European
+ Accessibility Act and avoid potentially triggering photosensitive
+ seizures
+ (mutter!4487 upstream)
+ - Fix a rare crash with a NULL pointer dereference
+ (mutter#4147 upstream, LP: #2100243)
+ - Avoid reopening an inactive Nvidia GPU when not needed
+ (mutter#3550 upstream)
+ - Fix a NULL dereference in the tests
+ (mutter!4495 upstream)
+ - Fix stacking order for windows that get activated before mapped
+ (mutter!4462 upstream)
+ - Fix incorrect cursor over Xwayland clients
+ (mutter#4033 upstream, LP: #2111502)
+ - Improve Wayland spec compliance by sending Wayland seat name before
+ its capabilities
+ (mutter#4119 upstream)
+ - Improve X11 compatibility (especially in Wine) by moving the X11 focus
+ to a shared dummy window when the Wayland focus is really on any
+ non-X11 window
+ (mutter!4447 upstream)
+ - Wait longer for hotplugged monitors to detect their input sources,
+ improving compatibility with e.g. MSI PRO MP275Q
+ (mutter!4442 upstream)
+ - Make sure the cursor is updated after modesetting, even if there is no
+ application window to redraw
+ (mutter!4452 upstream)
+ - Fix high resolution scroll events getting converted to discrete events
+ that intermittently switch direction
+ (mutter#4128 upstream)
+ - Documentation updates
+
+ [ Simon McVittie ]
+ * d/gbp.conf: Use upstream/48.x branch for trixie
+ * d/watch: Only watch for 48.x releases
+
+ -- Jeremy Bícha <jbicha@ubuntu.com> Thu, 03 Jul 2025 08:48:17 -0400
+
mutter (48.3.1-2) unstable; urgency=medium
* Team upload
diff -Nru mutter-48.3.1/debian/control mutter-48.4/debian/control
--- mutter-48.3.1/debian/control 2025-06-14 10:07:10.000000000 +0100
+++ mutter-48.4/debian/control 2025-07-13 12:27:01.000000000 +0100
@@ -102,7 +102,7 @@
Rules-Requires-Root: no
Standards-Version: 4.7.0
Homepage: https://mutter.gnome.org/
-Vcs-Git: https://salsa.debian.org/gnome-team/mutter.git
+Vcs-Git: https://salsa.debian.org/gnome-team/mutter.git -b debian/trixie
Vcs-Browser: https://salsa.debian.org/gnome-team/mutter
Package: mutter
diff -Nru mutter-48.3.1/debian/gbp.conf mutter-48.4/debian/gbp.conf
--- mutter-48.3.1/debian/gbp.conf 2025-06-14 10:07:10.000000000 +0100
+++ mutter-48.4/debian/gbp.conf 2025-07-13 12:27:01.000000000 +0100
@@ -1,7 +1,7 @@
[DEFAULT]
pristine-tar = True
-debian-branch = debian/latest
-upstream-branch = upstream/latest
+debian-branch = debian/trixie
+upstream-branch = upstream/48.x
[buildpackage]
sign-tags = True
diff -Nru mutter-48.3.1/debian/watch mutter-48.4/debian/watch
--- mutter-48.3.1/debian/watch 2025-06-14 10:07:10.000000000 +0100
+++ mutter-48.4/debian/watch 2025-07-13 12:27:01.000000000 +0100
@@ -1,4 +1,4 @@
version=4
opts="searchmode=plain, uversionmangle=s/\.(alpha|beta|rc)/~$1/, downloadurlmangle=s|cache.json||" \
https://download.gnome.org/sources/@PACKAGE@/cache.json \
- [\d.]+/@PACKAGE@@ANY_VERSION@@ARCHIVE_EXT@
+ 48/@PACKAGE@-([\d.]+)@ARCHIVE_EXT@
diff -Nru mutter-48.3.1/doc/reference/clutter/clutter.toml.in mutter-48.4/doc/reference/clutter/clutter.toml.in
--- mutter-48.3.1/doc/reference/clutter/clutter.toml.in 2025-06-02 23:01:18.000000000 +0100
+++ mutter-48.4/doc/reference/clutter/clutter.toml.in 2025-06-29 11:00:20.000000000 +0100
@@ -2,8 +2,8 @@
version = "@version@"
browse_url = "https://gitlab.gnome.org/GNOME/mutter/"
repository_url = "https://gitlab.gnome.org/GNOME/mutter.git"
-website_url = "https://blogs.gnome.org/shell-dev/"
-docs_url = "https://mutter.gnome.org/"
+website_url = "https://mutter.gnome.org"
+docs_url = "https://mutter.gnome.org/clutter"
logo_url = "logo.svg"
authors = "Mutter Development Team"
license = "GPL-2.0-or-later"
diff -Nru mutter-48.3.1/doc/reference/cogl/cogl.toml.in mutter-48.4/doc/reference/cogl/cogl.toml.in
--- mutter-48.3.1/doc/reference/cogl/cogl.toml.in 2025-06-02 23:01:18.000000000 +0100
+++ mutter-48.4/doc/reference/cogl/cogl.toml.in 2025-06-29 11:00:20.000000000 +0100
@@ -2,8 +2,8 @@
version = "@version@"
browse_url = "https://gitlab.gnome.org/GNOME/mutter/"
repository_url = "https://gitlab.gnome.org/GNOME/mutter.git"
-website_url = "https://blogs.gnome.org/shell-dev/"
-docs_url = "https://mutter.gnome.org/"
+website_url = "https://mutter.gnome.org"
+docs_url = "https://mutter.gnome.org/cogl"
logo_url = "logo.svg"
authors = "Mutter Development Team"
license = "GPL-2.0-or-later"
diff -Nru mutter-48.3.1/doc/reference/meta/meta.toml.in mutter-48.4/doc/reference/meta/meta.toml.in
--- mutter-48.3.1/doc/reference/meta/meta.toml.in 2025-06-02 23:01:18.000000000 +0100
+++ mutter-48.4/doc/reference/meta/meta.toml.in 2025-06-29 11:00:20.000000000 +0100
@@ -2,8 +2,8 @@
version = "@version@"
browse_url = "https://gitlab.gnome.org/GNOME/mutter/"
repository_url = "https://gitlab.gnome.org/GNOME/mutter.git"
-website_url = "https://blogs.gnome.org/shell-dev/"
-docs_url = "https://mutter.gnome.org/"
+website_url = "https://mutter.gnome.org"
+docs_url = "https://mutter.gnome.org/meta"
logo_url = "logo.svg"
authors = "Mutter Development Team"
license = "GPL-2.0-or-later"
diff -Nru mutter-48.3.1/doc/reference/mtk/mtk.toml.in mutter-48.4/doc/reference/mtk/mtk.toml.in
--- mutter-48.3.1/doc/reference/mtk/mtk.toml.in 2025-06-02 23:01:18.000000000 +0100
+++ mutter-48.4/doc/reference/mtk/mtk.toml.in 2025-06-29 11:00:20.000000000 +0100
@@ -2,8 +2,8 @@
version = "@version@"
browse_url = "https://gitlab.gnome.org/GNOME/mutter/"
repository_url = "https://gitlab.gnome.org/GNOME/mutter.git"
-website_url = "https://blogs.gnome.org/shell-dev/"
-docs_url = "https://mutter.gnome.org/"
+website_url = "https://mutter.gnome.org"
+docs_url = "https://mutter.gnome.org/mtk"
logo_url = "logo.svg"
authors = "Mutter Development Team"
license = "GPL-2.0-or-later"
diff -Nru mutter-48.3.1/doc/website/index.html mutter-48.4/doc/website/index.html
--- mutter-48.3.1/doc/website/index.html 2025-06-02 23:01:18.000000000 +0100
+++ mutter-48.4/doc/website/index.html 2025-06-29 11:00:20.000000000 +0100
@@ -126,6 +126,7 @@
<li><a
href="https://gitlab.gnome.org/GNOME/mutter/-/jobs/artifacts/main/file/coveragereport/index.html?job=coverage">Code
Coverage Report</a></li>
+ <li><a href="https://blogs.gnome.org/shell-dev/">Development blog</a></li>
</ul>
</div>
diff -Nru mutter-48.3.1/meson.build mutter-48.4/meson.build
--- mutter-48.3.1/meson.build 2025-06-02 23:01:18.000000000 +0100
+++ mutter-48.4/meson.build 2025-06-29 11:00:20.000000000 +0100
@@ -1,5 +1,5 @@
project('mutter', 'c',
- version: '48.3.1',
+ version: '48.4',
meson_version: '>= 1.3.0',
license: 'GPL-2.0-or-later',
)
diff -Nru mutter-48.3.1/NEWS mutter-48.4/NEWS
--- mutter-48.3.1/NEWS 2025-06-02 23:01:18.000000000 +0100
+++ mutter-48.4/NEWS 2025-06-29 11:00:20.000000000 +0100
@@ -1,3 +1,21 @@
+48.4
+====
+* Unlink outputs from unused connectors in update_outputs [Michel; !4474]
+* Add speed limit to Visual alerts [Sergio; !4487]
+* Fix behavior of windows that get activated before mapped [Alessandro; !4462]
+* Fix incorrect cursor over Xwayland clients [Carlos; !4433]
+* Fix hi-res scroll events getting converted to flip-flopping discrete events
+ [Peter; !4459]
+* Fixed crash [Daniel; !4303]
+* Misc. bug fixes and cleanups [Alessandro, Jonas, Jordan, Alessandro, Corentin,
+ Daniel, Lukáš, Rémi, Michel; !4481, !4482, !4485, !4492, !4496, !4495, !4444,
+ !4447, !4442, !4452]
+
+Contributors:
+ Alessandro Astone, Rémi Bernon, Sergio Costas Rodriguez, Michel Dänzer,
+ Carlos Garnacho, Peter Hutterer, Corentin Noël, Jordan Petridis,
+ Lukáš Tyrychtr, Daniel van Vugt, Jonas Ådahl
+
48.3.1
======
* Fix Xwayland windows becoming unresponsive to events [Jonas; !4475]
diff -Nru mutter-48.3.1/src/backends/native/meta-gpu-kms.c mutter-48.4/src/backends/native/meta-gpu-kms.c
--- mutter-48.3.1/src/backends/native/meta-gpu-kms.c 2025-06-02 23:01:18.000000000 +0100
+++ mutter-48.4/src/backends/native/meta-gpu-kms.c 2025-06-29 11:00:20.000000000 +0100
@@ -351,6 +351,8 @@
MetaOutput *old_output;
GError *error = NULL;
+ meta_unlink_kms_connector (kms_connector);
+
if (!meta_kms_connector_get_current_state (kms_connector))
continue;
diff -Nru mutter-48.3.1/src/backends/native/meta-kms.c mutter-48.4/src/backends/native/meta-kms.c
--- mutter-48.3.1/src/backends/native/meta-kms.c 2025-06-02 23:01:18.000000000 +0100
+++ mutter-48.4/src/backends/native/meta-kms.c 2025-06-29 11:00:20.000000000 +0100
@@ -373,7 +373,7 @@
}
ensure_hotplug_timeout_source (kms);
- g_source_set_ready_time (kms->hotplug_timeout, now + 2 * G_USEC_PER_SEC);
+ g_source_set_ready_time (kms->hotplug_timeout, now + 3 * G_USEC_PER_SEC);
g_hash_table_insert (kms->hotplug_events, g_steal_pointer (&hotplug_event),
NULL);
diff -Nru mutter-48.3.1/src/backends/native/meta-kms-impl-device.c mutter-48.4/src/backends/native/meta-kms-impl-device.c
--- mutter-48.3.1/src/backends/native/meta-kms-impl-device.c 2025-06-02 23:01:18.000000000 +0100
+++ mutter-48.4/src/backends/native/meta-kms-impl-device.c 2025-06-29 11:00:20.000000000 +0100
@@ -1131,11 +1131,13 @@
drmModeRes *drm_resources;
MetaKmsResourceChanges changes;
GList *l;
+ gboolean had_fd_open;
meta_assert_in_kms_impl (meta_kms_impl_get_kms (priv->impl));
meta_topic (META_DEBUG_KMS, "Updating device state for %s", priv->path);
+ had_fd_open = !!priv->device_file;
if (!ensure_device_file (impl_device, &error))
{
g_warning ("Failed to reopen '%s': %s", priv->path, error->message);
@@ -1172,6 +1174,9 @@
drmModeFreeResources (drm_resources);
+ if (changes == META_KMS_RESOURCE_CHANGE_NONE && !had_fd_open)
+ clear_latched_fd_hold (impl_device);
+
return changes;
err:
@@ -1781,11 +1786,14 @@
crtc_frame = get_crtc_frame (impl_device, latch_crtc);
if (!crtc_frame)
{
+ const MetaKmsCrtcState *crtc_state =
+ meta_kms_crtc_get_current_state (latch_crtc);
+
crtc_frame = g_new0 (CrtcFrame, 1);
crtc_frame->impl_device = impl_device;
crtc_frame->crtc = latch_crtc;
crtc_frame->deadline.timer_fd = -1;
- crtc_frame->await_flush = TRUE;
+ crtc_frame->await_flush = !crtc_state->is_active;
g_hash_table_insert (priv->crtc_frames, latch_crtc, crtc_frame);
}
diff -Nru mutter-48.3.1/src/backends/native/meta-onscreen-native.c mutter-48.4/src/backends/native/meta-onscreen-native.c
--- mutter-48.3.1/src/backends/native/meta-onscreen-native.c 2025-06-02 23:01:18.000000000 +0100
+++ mutter-48.4/src/backends/native/meta-onscreen-native.c 2025-06-29 11:00:20.000000000 +0100
@@ -1833,7 +1833,7 @@
g_warning ("Direct scanout page flip failed: %s", error->message);
cogl_scanout_notify_failed (scanout, onscreen);
- if (onscreen_native->next_frame == NULL)
+ if (onscreen_native->next_frame == NULL && view != NULL)
{
clutter_stage_view_add_redraw_clip (view, NULL);
clutter_stage_view_schedule_update_now (view);
diff -Nru mutter-48.3.1/src/backends/native/meta-output-kms.c mutter-48.4/src/backends/native/meta-output-kms.c
--- mutter-48.3.1/src/backends/native/meta-output-kms.c 2025-06-02 23:01:18.000000000 +0100
+++ mutter-48.4/src/backends/native/meta-output-kms.c 2025-06-29 11:00:20.000000000 +0100
@@ -99,6 +99,17 @@
kms_connector_output_kms_quark);
}
+void
+meta_unlink_kms_connector (MetaKmsConnector *connector)
+{
+ if (!kms_connector_output_kms_quark)
+ return;
+
+ g_object_set_qdata (G_OBJECT (connector),
+ kms_connector_output_kms_quark,
+ NULL);
+}
+
static GBytes *
meta_output_kms_read_edid (MetaOutputNative *output_native)
{
diff -Nru mutter-48.3.1/src/backends/native/meta-output-kms.h mutter-48.4/src/backends/native/meta-output-kms.h
--- mutter-48.3.1/src/backends/native/meta-output-kms.h 2025-06-02 23:01:18.000000000 +0100
+++ mutter-48.4/src/backends/native/meta-output-kms.h 2025-06-29 11:00:20.000000000 +0100
@@ -41,6 +41,8 @@
MetaOutputKms * meta_output_kms_from_kms_connector (MetaKmsConnector *connector);
+void meta_unlink_kms_connector (MetaKmsConnector *connector);
+
MetaOutputKms * meta_output_kms_new (MetaGpuKms *gpu_kms,
MetaKmsConnector *kms_connector,
MetaOutput *old_output,
diff -Nru mutter-48.3.1/src/backends/native/meta-seat-impl.c mutter-48.4/src/backends/native/meta-seat-impl.c
--- mutter-48.3.1/src/backends/native/meta-seat-impl.c 2025-06-02 23:01:18.000000000 +0100
+++ mutter-48.4/src/backends/native/meta-seat-impl.c 2025-06-29 11:00:20.000000000 +0100
@@ -1218,7 +1218,7 @@
evdev_device->value120.acc_dx += (int32_t) dx_value120;
evdev_device->value120.acc_dy += (int32_t) dy_value120;
- if (abs (evdev_device->value120.acc_dx) >= 60)
+ if (dx_value120 != 0 && abs (evdev_device->value120.acc_dx) >= 60)
{
low_res_value = (evdev_device->value120.acc_dx / 120);
if (low_res_value == 0)
@@ -1230,7 +1230,7 @@
evdev_device->value120.acc_dx -= (low_res_value * 120);
}
- if (abs (evdev_device->value120.acc_dy) >= 60)
+ if (dy_value120 != 0 && abs (evdev_device->value120.acc_dy) >= 60)
{
low_res_value = (evdev_device->value120.acc_dy / 120);
if (low_res_value == 0)
diff -Nru mutter-48.3.1/src/compositor/compositor.c mutter-48.4/src/compositor/compositor.c
--- mutter-48.3.1/src/compositor/compositor.c 2025-06-02 23:01:18.000000000 +0100
+++ mutter-48.4/src/compositor/compositor.c 2025-06-29 11:00:20.000000000 +0100
@@ -1282,7 +1282,8 @@
void
meta_compositor_flash_display (MetaCompositor *compositor,
- MetaDisplay *display)
+ MetaDisplay *display,
+ int n_flashes)
{
MetaBackend *backend;
ClutterActor *stage;
@@ -1308,7 +1309,7 @@
transition = clutter_actor_get_transition (flash, "opacity");
clutter_timeline_set_auto_reverse (CLUTTER_TIMELINE (transition), TRUE);
- clutter_timeline_set_repeat_count (CLUTTER_TIMELINE (transition), 2);
+ clutter_timeline_set_repeat_count (CLUTTER_TIMELINE (transition), n_flashes);
g_signal_connect (transition, "stopped",
G_CALLBACK (flash_out_completed), flash);
@@ -1327,7 +1328,8 @@
void
meta_compositor_flash_window (MetaCompositor *compositor,
- MetaWindow *window)
+ MetaWindow *window,
+ int n_flashes)
{
ClutterActor *window_actor =
CLUTTER_ACTOR (meta_window_actor_from_window (window));
@@ -1356,7 +1358,7 @@
if (transition)
{
clutter_timeline_set_auto_reverse (CLUTTER_TIMELINE (transition), TRUE);
- clutter_timeline_set_repeat_count (CLUTTER_TIMELINE (transition), 2);
+ clutter_timeline_set_repeat_count (CLUTTER_TIMELINE (transition), n_flashes);
g_signal_connect (transition, "stopped",
G_CALLBACK (window_flash_out_completed), flash);
diff -Nru mutter-48.3.1/src/compositor/compositor-private.h mutter-48.4/src/compositor/compositor-private.h
--- mutter-48.3.1/src/compositor/compositor-private.h 2025-06-02 23:01:18.000000000 +0100
+++ mutter-48.4/src/compositor/compositor-private.h 2025-06-29 11:00:20.000000000 +0100
@@ -52,7 +52,8 @@
int64_t monotonic_time_us);
void meta_compositor_flash_window (MetaCompositor *compositor,
- MetaWindow *window);
+ MetaWindow *window,
+ int n_flashes);
MetaCloseDialog * meta_compositor_create_close_dialog (MetaCompositor *compositor,
MetaWindow *window);
@@ -141,7 +142,8 @@
GList *stack);
void meta_compositor_flash_display (MetaCompositor *compositor,
- MetaDisplay *display);
+ MetaDisplay *display,
+ int n_flashes);
void meta_compositor_show_tile_preview (MetaCompositor *compositor,
MetaWindow *window,
diff -Nru mutter-48.3.1/src/core/bell.c mutter-48.4/src/core/bell.c
--- mutter-48.3.1/src/core/bell.c 2025-06-02 23:01:18.000000000 +0100
+++ mutter-48.4/src/core/bell.c 2025-06-29 11:00:20.000000000 +0100
@@ -54,6 +54,11 @@
#include "core/util-private.h"
#include "core/window-private.h"
#include "meta/compositor.h"
+#include "mtk/mtk.h"
+
+/* Time limits to prevent Photosensitive Seizures */
+#define MIN_TIME_BETWEEN_VISUAL_ALERTS_MS 500
+#define MIN_TIME_BETWEEN_DOUBLE_VISUAL_ALERT_MS 3000
G_DEFINE_TYPE (MetaBell, meta_bell, G_TYPE_OBJECT)
@@ -120,7 +125,7 @@
/**
* bell_flash_fullscreen:
* @display: The display the event came in on
- * @xkb_ev: The bell event
+ * @n_flashes: The number of times to flash the screen
*
* Flashes one screen, or all screens, in response to a bell event.
* If the event is on a particular window, flash the screen that
@@ -129,15 +134,17 @@
* If the configure script found we had no XKB, this does not exist.
*/
static void
-bell_flash_fullscreen (MetaDisplay *display)
+bell_flash_fullscreen (MetaDisplay *display,
+ int n_flashes)
{
- meta_compositor_flash_display (display->compositor, display);
+ meta_compositor_flash_display (display->compositor, display, n_flashes);
}
static void
-bell_flash_window (MetaWindow *window)
+bell_flash_window (MetaWindow *window,
+ int n_flashes)
{
- meta_compositor_flash_window (window->display->compositor, window);
+ meta_compositor_flash_window (window->display->compositor, window, n_flashes);
}
/**
@@ -150,12 +157,13 @@
*/
static void
bell_flash_frame (MetaDisplay *display,
- MetaWindow *window)
+ MetaWindow *window,
+ int n_flashes)
{
if (window)
- bell_flash_window (window);
+ bell_flash_window (window, n_flashes);
else
- bell_flash_fullscreen (display);
+ bell_flash_fullscreen (display, n_flashes);
}
/**
@@ -170,13 +178,49 @@
bell_visual_notify (MetaDisplay *display,
MetaWindow *window)
{
+ /*
+ * The European Accessibility Act (EAA), in the Annex I, Section I, 2.J,
+ * specifies that products "shall avoid triggering photosensitive seizures".
+ *
+ * According to the Web Content Accessibility Guidelines (WCAG), any
+ * element that flashes in the screen must have a maximum period of
+ * 3Hz to avoid the risk of Photosensitivity Seizures.
+ *
+ * If several alarm bells are sent fast enough, the Visual alerts could
+ * flash the screen or the window at speeds about 8-9Hz (tested with a
+ * simple BASH script), which is greater than the currently accepted
+ * limit of 3Hz.
+ *
+ * To avoid this, a timeout is added to ensure that no visual alerts are
+ * sent with less than 500ms of difference, to set a maximum flash speed
+ * of 2Hz.
+ *
+ * A property in display is used to keep the last time a visual alert has been
+ * sent because not only a "single flash zone" can trigger a seizure, but also
+ * slower patterns combined. So a global timeout for all the desktop is the
+ * safest approach.
+ */
+ int64_t now_us;
+ int64_t time_difference_ms;
+ int n_flashes;
+
+ now_us = g_get_monotonic_time ();
+ time_difference_ms = us2ms (now_us - display->last_visual_bell_time_us);
+
+ if (time_difference_ms < MIN_TIME_BETWEEN_VISUAL_ALERTS_MS)
+ return;
+
+ display->last_visual_bell_time_us = now_us;
+
+ n_flashes = (time_difference_ms < MIN_TIME_BETWEEN_DOUBLE_VISUAL_ALERT_MS) ? 1 : 2;
+
switch (meta_prefs_get_visual_bell_type ())
{
case G_DESKTOP_VISUAL_BELL_FULLSCREEN_FLASH:
- bell_flash_fullscreen (display);
+ bell_flash_fullscreen (display, n_flashes);
break;
case G_DESKTOP_VISUAL_BELL_FRAME_FLASH:
- bell_flash_frame (display, window);
+ bell_flash_frame (display, window, n_flashes);
break;
}
}
diff -Nru mutter-48.3.1/src/core/display-private.h mutter-48.4/src/core/display-private.h
--- mutter-48.3.1/src/core/display-private.h 2025-06-02 23:01:18.000000000 +0100
+++ mutter-48.4/src/core/display-private.h 2025-06-29 11:00:20.000000000 +0100
@@ -120,11 +120,11 @@
GSList *pending_pings;
/* Pending focus change */
- guint focus_timeout_id;
+ guint focus_timeout_id;
/* Pending autoraise */
- guint autoraise_timeout_id;
- MetaWindow* autoraise_window;
+ guint autoraise_timeout_id;
+ MetaWindow *autoraise_window;
MetaKeyBindingManager key_binding_manager;
@@ -157,6 +157,7 @@
guint check_fullscreen_later;
MetaBell *bell;
+ int64_t last_visual_bell_time_us;
MetaWorkspaceManager *workspace_manager;
MetaSoundPlayer *sound_player;
diff -Nru mutter-48.3.1/src/core/meta-context-main.c mutter-48.4/src/core/meta-context-main.c
--- mutter-48.3.1/src/core/meta-context-main.c 2025-06-02 23:01:18.000000000 +0100
+++ mutter-48.4/src/core/meta-context-main.c 2025-06-29 11:00:20.000000000 +0100
@@ -666,6 +666,8 @@
N_("Run as a nested compositor"),
NULL
},
+#endif
+#ifdef HAVE_XWAYLAND
{
"no-x11", 0, 0, G_OPTION_ARG_NONE,
&context_main->options.no_x11,
diff -Nru mutter-48.3.1/src/core/window.c mutter-48.4/src/core/window.c
--- mutter-48.3.1/src/core/window.c 2025-06-02 23:01:18.000000000 +0100
+++ mutter-48.4/src/core/window.c 2025-06-29 11:00:20.000000000 +0100
@@ -5181,6 +5181,13 @@
g_return_if_fail (!window->override_redirect);
+ /* Flush pending visible state now.
+ * It is important that this runs before meta_stack_raise() because
+ * showing a window may overwrite its stacking order based on the
+ * stacking rules for newly shown windows.
+ */
+ meta_window_flush_calc_showing (window);
+
ancestor = meta_window_find_root_ancestor (window);
meta_topic (META_DEBUG_WINDOW_OPS,
diff -Nru mutter-48.3.1/src/tests/test-runner.c mutter-48.4/src/tests/test-runner.c
--- mutter-48.3.1/src/tests/test-runner.c 2025-06-02 23:01:18.000000000 +0100
+++ mutter-48.4/src/tests/test-runner.c 2025-06-29 11:00:20.000000000 +0100
@@ -296,7 +296,7 @@
if ((filter & STACK_FILTER_SHOWING) && window && window->hidden)
continue;
- if (workspace && !meta_window_located_on_workspace (window, workspace))
+ if (window && workspace && !meta_window_located_on_workspace (window, workspace))
continue;
if (window != NULL && window->title)
diff -Nru mutter-48.3.1/src/wayland/meta-wayland-data-device.c mutter-48.4/src/wayland/meta-wayland-data-device.c
--- mutter-48.3.1/src/wayland/meta-wayland-data-device.c 2025-06-02 23:01:18.000000000 +0100
+++ mutter-48.4/src/wayland/meta-wayland-data-device.c 2025-06-29 11:00:20.000000000 +0100
@@ -26,8 +26,6 @@
#include "wayland/meta-wayland-data-device.h"
-#include <gio/gunixoutputstream.h>
-#include <glib-unix.h>
#include <glib.h>
#include <stdio.h>
#include <stdlib.h>
@@ -235,6 +233,12 @@
g_autoptr (MetaCursorSprite) cursor_sprite = NULL;
MetaCursorRenderer *cursor_renderer;
+#ifdef HAVE_X11_CLIENT
+ /* X11 DnD lets the drag source client drive pointer cursor updates */
+ if (META_IS_WAYLAND_DATA_SOURCE_XWAYLAND (drag_grab->drag_data_source))
+ return;
+#endif
+
cursor_sprite =
META_CURSOR_SPRITE (meta_cursor_sprite_xcursor_new (cursor, cursor_tracker));
cursor_renderer =
@@ -276,10 +280,7 @@
on_data_source_action_changed (MetaWaylandDataSource *source,
MetaWaylandDragGrab *drag_grab)
{
-#ifdef HAVE_X11_CLIENT
- if (!META_IS_WAYLAND_DATA_SOURCE_XWAYLAND (source))
-#endif
- meta_wayland_drag_grab_update_cursor (drag_grab);
+ meta_wayland_drag_grab_update_cursor (drag_grab);
}
static void
@@ -453,6 +454,8 @@
MetaDisplay *display = display_from_data_device (data_device);
MetaCompositor *compositor = meta_display_get_compositor (display);
+ meta_wayland_drag_grab_set_cursor (drag_grab, META_CURSOR_DEFAULT);
+
meta_wayland_drag_grab_set_source (drag_grab, NULL);
meta_wayland_drag_grab_set_focus (drag_grab, NULL);
@@ -485,55 +488,11 @@
drag_grab->handler = NULL;
}
- meta_wayland_drag_grab_set_cursor (drag_grab, META_CURSOR_DEFAULT);
meta_dnd_wayland_handle_end_modal (compositor);
g_free (drag_grab);
}
-static gboolean
-on_fake_read_hup (GIOChannel *channel,
- GIOCondition condition,
- gpointer data)
-{
- MetaWaylandDataSource *source = data;
-
- meta_wayland_data_source_notify_finish (source);
- g_io_channel_shutdown (channel, FALSE, NULL);
- g_io_channel_unref (channel);
-
- return G_SOURCE_REMOVE;
-}
-
-static void
-meta_wayland_data_source_fake_read (MetaWaylandDataSource *source,
- const gchar *mimetype)
-{
- GIOChannel *channel;
- int p[2];
-
- if (!g_unix_open_pipe (p, FD_CLOEXEC, NULL))
- {
- meta_wayland_data_source_notify_finish (source);
- return;
- }
-
- if (!g_unix_set_fd_nonblocking (p[0], TRUE, NULL) ||
- !g_unix_set_fd_nonblocking (p[1], TRUE, NULL))
- {
- meta_wayland_data_source_notify_finish (source);
- close (p[0]);
- close (p[1]);
- return;
- }
-
- meta_wayland_data_source_send (source, mimetype, p[1]);
- close (p[1]);
- channel = g_io_channel_unix_new (p[0]);
- g_io_channel_set_close_on_unref (channel, TRUE);
- g_io_add_watch (channel, G_IO_HUP, on_fake_read_hup, source);
-}
-
static MetaWaylandSurface *
drag_grab_get_focus_surface (MetaWaylandEventHandler *handler,
ClutterInputDevice *device,
diff -Nru mutter-48.3.1/src/wayland/meta-wayland-data-source.c mutter-48.4/src/wayland/meta-wayland-data-source.c
--- mutter-48.3.1/src/wayland/meta-wayland-data-source.c 2025-06-02 23:01:18.000000000 +0100
+++ mutter-48.4/src/wayland/meta-wayland-data-source.c 2025-06-29 11:00:20.000000000 +0100
@@ -23,6 +23,8 @@
#include "config.h"
+#include <gio/gunixoutputstream.h>
+#include <glib-unix.h>
#include <unistd.h>
#include "wayland/meta-wayland-data-source.h"
@@ -46,6 +48,10 @@
enum wl_data_device_manager_dnd_action current_dnd_action;
MetaWaylandSeat *seat;
MetaWaylandToplevelDrag *toplevel_drag;
+
+ GIOChannel *fake_read_channel;
+ guint fake_read_watch_id;
+
guint actions_set : 1;
guint in_ask : 1;
guint drop_performed : 1;
@@ -160,6 +166,9 @@
meta_wayland_data_source_get_instance_private (source);
char **pos;
+ g_clear_handle_id (&priv->fake_read_watch_id, g_source_remove);
+ g_clear_pointer (&priv->fake_read_channel, g_io_channel_unref);
+
wl_array_for_each (pos, &priv->mime_types)
g_free (*pos);
wl_array_release (&priv->mime_types);
@@ -582,6 +591,56 @@
META_WAYLAND_DATA_SOURCE_GET_CLASS (source)->drag_finished (source);
}
+static gboolean
+on_fake_read_hup (GIOChannel *channel,
+ GIOCondition condition,
+ gpointer user_data)
+{
+ MetaWaylandDataSource *source = META_WAYLAND_DATA_SOURCE (user_data);
+ MetaWaylandDataSourcePrivate *priv =
+ meta_wayland_data_source_get_instance_private (source);
+
+ priv->fake_read_watch_id = 0;
+ meta_wayland_data_source_notify_finish (source);
+ g_io_channel_shutdown (channel, FALSE, NULL);
+ g_clear_pointer (&priv->fake_read_channel, g_io_channel_unref);
+
+ return G_SOURCE_REMOVE;
+}
+
+void
+meta_wayland_data_source_fake_read (MetaWaylandDataSource *source,
+ const char *mimetype)
+{
+ MetaWaylandDataSourcePrivate *priv =
+ meta_wayland_data_source_get_instance_private (source);
+ GIOChannel *channel;
+ int p[2];
+
+ if (!g_unix_open_pipe (p, FD_CLOEXEC, NULL))
+ {
+ meta_wayland_data_source_notify_finish (source);
+ return;
+ }
+
+ if (!g_unix_set_fd_nonblocking (p[0], TRUE, NULL) ||
+ !g_unix_set_fd_nonblocking (p[1], TRUE, NULL))
+ {
+ meta_wayland_data_source_notify_finish (source);
+ close (p[0]);
+ close (p[1]);
+ return;
+ }
+
+ meta_wayland_data_source_send (source, mimetype, p[1]);
+ close (p[1]);
+ channel = g_io_channel_unix_new (p[0]);
+ g_io_channel_set_close_on_unref (channel, TRUE);
+ priv->fake_read_channel = channel;
+ priv->fake_read_watch_id =
+ g_io_add_watch (channel, G_IO_HUP, on_fake_read_hup, source);
+}
+
gboolean
meta_wayland_data_source_add_mime_type (MetaWaylandDataSource *source,
const char *mime_type)
diff -Nru mutter-48.3.1/src/wayland/meta-wayland-data-source.h mutter-48.4/src/wayland/meta-wayland-data-source.h
--- mutter-48.3.1/src/wayland/meta-wayland-data-source.h 2025-06-02 23:01:18.000000000 +0100
+++ mutter-48.4/src/wayland/meta-wayland-data-source.h 2025-06-29 11:00:20.000000000 +0100
@@ -111,6 +111,9 @@
void meta_wayland_data_source_notify_drop_performed (MetaWaylandDataSource *source);
void meta_wayland_data_source_notify_finish (MetaWaylandDataSource *source);
+void meta_wayland_data_source_fake_read (MetaWaylandDataSource *source,
+ const char *mimetype);
+
void
meta_wayland_data_source_set_toplevel_drag (MetaWaylandDataSource *source,
MetaWaylandToplevelDrag *toplevel_drag);
diff -Nru mutter-48.3.1/src/wayland/meta-wayland-seat.c mutter-48.4/src/wayland/meta-wayland-seat.c
--- mutter-48.3.1/src/wayland/meta-wayland-seat.c 2025-06-02 23:01:18.000000000 +0100
+++ mutter-48.4/src/wayland/meta-wayland-seat.c 2025-06-29 11:00:20.000000000 +0100
@@ -98,10 +98,10 @@
wl_resource_set_implementation (resource, &seat_interface, seat, unbind_resource);
wl_list_insert (&seat->base_resource_list, wl_resource_get_link (resource));
- wl_seat_send_capabilities (resource, seat->capabilities);
-
if (version >= WL_SEAT_NAME_SINCE_VERSION)
wl_seat_send_name (resource, "seat0");
+
+ wl_seat_send_capabilities (resource, seat->capabilities);
}
static uint32_t
diff -Nru mutter-48.3.1/src/x11/meta-x11-display.c mutter-48.4/src/x11/meta-x11-display.c
--- mutter-48.3.1/src/x11/meta-x11-display.c 2025-06-02 23:01:18.000000000 +0100
+++ mutter-48.4/src/x11/meta-x11-display.c 2025-06-29 11:00:20.000000000 +0100
@@ -2261,6 +2261,14 @@
if (focus_window)
data[0] = meta_window_x11_get_xwindow (focus_window);
+#ifdef HAVE_XWAYLAND
+ else if (x11_display->focus_xwindow && meta_is_wayland_compositor ())
+ /* On Wayland, when a Wayland window is focused, indicate that an
+ * actual window is focused rather than None, as None is otherwise
+ * also used during transient focus changes.
+ */
+ data[0] = x11_display->no_focus_window;
+#endif
else
data[0] = None;
Reply to: