Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package wayland for openSUSE:Factory checked 
in at 2026-07-17 18:47:42
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/wayland (Old)
 and      /work/SRC/openSUSE:Factory/.wayland.new.24530 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "wayland"

Fri Jul 17 18:47:42 2026 rev:56 rq:1366220 version:1.26.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/wayland/wayland.changes  2026-03-22 
14:11:38.256039657 +0100
+++ /work/SRC/openSUSE:Factory/.wayland.new.24530/wayland.changes       
2026-07-17 18:48:31.991336481 +0200
@@ -1,0 +2,14 @@
+Thu Jul 16 16:01:24 UTC 2026 - Jan Engelhardt <[email protected]>
+
+- Update to release 1.26
+  * A new wl_pointer.warp event, to notify a new pointer position
+    without an end-user-initiated motion event.
+  * A new wl_fixes.ack_global_remove request, to address races
+    related to global remove events.
+  * A new wl_display_remove_socket_fd() function to remove sockets
+    previously added via wl_display_add_socket_fd().
+  * WAYLAND_DEBUG timestamps now use the "HH:MM:ss.xxxxxx" format,
+    making them easier to read and compare with other logs.
+- Drop pre-Leap-16.x build logic
+
+-------------------------------------------------------------------

Old:
----
  wayland-1.25.0.tar.xz
  wayland-1.25.0.tar.xz.sig

New:
----
  wayland-1.26.0.tar.xz
  wayland-1.26.0.tar.xz.sig

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ wayland.spec ++++++
--- /var/tmp/diff_new_pack.EwpGtt/_old  2026-07-17 18:48:33.027371412 +0200
+++ /var/tmp/diff_new_pack.EwpGtt/_new  2026-07-17 18:48:33.047372087 +0200
@@ -16,12 +16,6 @@
 #
 
 
-%define _version 1.25.0
-%if 0%{?suse_version} >= 1500 && 0%{?suse_version} < 1550
-%define eglversion 99~%_version
-%else
-%define eglversion %_version
-%endif
 %define lname  libwayland0
 %define enable_test 1
 %if 0%{?qemu_user_space_build}
@@ -30,7 +24,7 @@
 %endif
 %bcond_with doc
 Name:           wayland
-Version:        %_version
+Version:        1.26.0
 Release:        0
 Summary:        Wayland Compositor Infrastructure
 License:        MIT
@@ -89,8 +83,7 @@
 to get buffer for each cursor image.
 
 %package -n libwayland-egl1
-Version:        %eglversion
-Summary:        Additional egl functions for wayland
+Summary:        Additional EGL functions for Wayland
 Group:          System/Libraries
 
 %description -n libwayland-egl1
@@ -113,20 +106,12 @@
 %package devel
 Summary:        Development files for the Wayland Compositor Infrastructure
 Group:          Development/Libraries/C and C++
-Requires:       libwayland-client0 = %_version
-Requires:       libwayland-cursor0 = %_version
-Requires:       libwayland-egl1 = %eglversion
-Requires:       libwayland-server0 = %_version
-%if 0%{?suse_version} >= 1500
-# egl1 was once provided by Mesa 17.x.
-%if (0%{?suse_version} >= 1550 || 0%{?sle_version} >= 150400)
+Requires:       libwayland-client0 = %version
+Requires:       libwayland-cursor0 = %version
+Requires:       libwayland-egl1 = %version
+Requires:       libwayland-server0 = %version
 Provides:       libwayland-egl-devel = 18.1.5
 Obsoletes:      libwayland-egl-devel < 18.1.5
-%else
-Provides:       libwayland-egl-devel = 18.0.2
-Obsoletes:      libwayland-egl-devel < 18.0.2
-%endif
-%endif
 
 %description devel
 Wayland is a protocol for a compositor to talk to its clients as well
@@ -149,7 +134,6 @@
 
 %prep
 %autosetup -p1
-sed -i 's/<eglversion>/%eglversion/' "%_sourcedir/baselibs.conf"
 
 %build
 # includedir intentional, cf. bugzilla.opensuse.org/795968
@@ -170,21 +154,10 @@
 %meson_test
 %endif
 
-%if 0%{?suse_version} >= 1550
 %ldconfig_scriptlets -n libwayland-client0
 %ldconfig_scriptlets -n libwayland-cursor0
 %ldconfig_scriptlets -n libwayland-egl1
 %ldconfig_scriptlets -n libwayland-server0
-%else
-%post   -n libwayland-client0 -p /sbin/ldconfig
-%postun -n libwayland-client0 -p /sbin/ldconfig
-%post   -n libwayland-cursor0 -p /sbin/ldconfig
-%postun -n libwayland-cursor0 -p /sbin/ldconfig
-%post   -n libwayland-egl1 -p /sbin/ldconfig
-%postun -n libwayland-egl1 -p /sbin/ldconfig
-%post   -n libwayland-server0 -p /sbin/ldconfig
-%postun -n libwayland-server0 -p /sbin/ldconfig
-%endif
 
 %files -n libwayland-client0
 %_libdir/libwayland-client.so.0*

++++++ _scmsync.obsinfo ++++++
--- /var/tmp/diff_new_pack.EwpGtt/_old  2026-07-17 18:48:33.359382606 +0200
+++ /var/tmp/diff_new_pack.EwpGtt/_new  2026-07-17 18:48:33.411384359 +0200
@@ -1,5 +1,5 @@
-mtime: 1773950034
-commit: 5107b46cec55f16ffdb1ff231a8c6c39ce965976dcfdfa2fcc466867373056af
+mtime: 1784217721
+commit: cba0cf7f7d93c560472b620ee6fd5488bf120bf166eeaccf1b6d981b39a4bdb1
 url: https://src.opensuse.org/jengelh/wayland
 revision: master
 

++++++ baselibs.conf ++++++
--- /var/tmp/diff_new_pack.EwpGtt/_old  2026-07-17 18:48:33.655392586 +0200
+++ /var/tmp/diff_new_pack.EwpGtt/_new  2026-07-17 18:48:33.687393666 +0200
@@ -6,7 +6,7 @@
        requires -wayland-<targettype>
        requires "libwayland-client0-<targettype> = <version>"
        requires "libwayland-cursor0-<targettype> = <version>"
-       requires "libwayland-egl1-<targettype> = <eglversion>"
+       requires "libwayland-egl1-<targettype> = <version>"
        requires "libwayland-server0-<targettype> = <version>"
        provides "libwayland-egl-devel-<targettype> = 18.1.5"
        obsoletes "libwayland-egl-devel-<targettype> < 18.1.5"

++++++ build.specials.obscpio ++++++

++++++ build.specials.obscpio ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/.gitignore new/.gitignore
--- old/.gitignore      1970-01-01 01:00:00.000000000 +0100
+++ new/.gitignore      2026-07-16 18:02:01.000000000 +0200
@@ -0,0 +1 @@
+.osc

++++++ wayland-1.25.0.tar.xz -> wayland-1.26.0.tar.xz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/wayland-1.25.0/.gitlab-ci.yml 
new/wayland-1.26.0/.gitlab-ci.yml
--- old/wayland-1.25.0/.gitlab-ci.yml   2026-03-19 17:03:08.000000000 +0100
+++ new/wayland-1.26.0/.gitlab-ci.yml   2026-07-16 17:24:51.000000000 +0200
@@ -305,11 +305,11 @@
 .os-freebsd:
   variables:
     BUILD_OS: freebsd
-    FDO_DISTRIBUTION_VERSION: "14.3"
+    FDO_DISTRIBUTION_VERSION: "14.4"
     FDO_DISTRIBUTION_PACKAGES: 'libxslt meson ninja pkgconf expat libffi 
libepoll-shim libxml2'
     # bump this tag every time you change something which requires rebuilding 
the
     # base image
-    FDO_DISTRIBUTION_TAG: "2025-07-20.0"
+    FDO_DISTRIBUTION_TAG: "2026-03-10.0"
     # Don't build documentation since installing the required tools massively
     # increases the VM image (and therefore container) size.
     MESON_ARGS: "--fatal-meson-warnings -Dwerror=true -Ddocumentation=false"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/wayland-1.25.0/doc/book/src/Protocol.md 
new/wayland-1.26.0/doc/book/src/Protocol.md
--- old/wayland-1.25.0/doc/book/src/Protocol.md 2026-03-19 17:03:08.000000000 
+0100
+++ new/wayland-1.26.0/doc/book/src/Protocol.md 2026-07-16 17:24:51.000000000 
+0200
@@ -170,9 +170,9 @@
 
 ## Connect Time
 
-There is no fixed connection setup information, the server emits multiple 
events
-at connect time, to indicate the presence and properties of global objects:
-outputs, compositor, input devices.
+When a client connects, the server sends no data but silently provides access 
to
+the singleton `wl_display` under object ID 1. Global objects are managed 
through
+an instance of [wl_registry](#registry).
 
 ## Security and Authentication
 
@@ -187,19 +187,50 @@
 
 Each object has a unique ID. The IDs are allocated by the entity creating the
 object (either client or server). IDs allocated by the client are in the range
-[1, 0xfeffffff] while IDs allocated by the server are in the range [0xff000000,
-0xffffffff]. The 0 ID is reserved to represent a null or non-existent object.
-For efficiency purposes, the IDs are densely packed in the sense that the ID N
-will not be used until N-1 has been used. This ordering is not merely a
-guideline, but a strict requirement, and there are implementations of the
-protocol that rigorously enforce this rule, including the ubiquitous 
libwayland.
+[2, 0xfeffffff] while IDs allocated by the server are in the range [0xff000000,
+0xffffffff]. The 0 ID is reserved to represent a null or non-existent object 
and
+ID 1 is automatically assigned to the singleton `wl_display` instance when a
+client connects. For efficiency purposes, the IDs are densely packed in the
+sense that the ID N will not be used until N-1 has been used. This ordering is
+not merely a guideline, but a strict requirement, and there are implementations
+of the protocol that rigorously enforce this rule, including the ubiquitous
+libwayland.
+
+## Display
+
+The display is a singleton global object and always has the ID 1. Clients often
+call its `get_registry` method after connecting to the server to obtain the
+object registry.
+
+See 
[wl_display](https://wayland.freedesktop.org/docs/html/apa.html#protocol-spec-wl_display)
+for the protocol description.
+
+## Registry
+
+The registry is a global object, instantiated using
+[`wl_display.get_registry`](https://wayland.freedesktop.org/docs/html/apa.html#protocol-spec-wl_display-request-get_registry),
+that acts as the interface to Wayland's object system between client and 
server:
+it initially informs the client of all globals available on the server,
+announces to the client whenever objects are added to or removed from the
+server, and allows the client to bind to the objects to interact with them.
+
+After instantiating a new registry, the server advertises all available objects
+to the client using
+[`wl_registry.global`](https://wayland.freedesktop.org/docs/html/apa.html#protocol-spec-wl_registry-event-global).
+Thereafter, whenever a new object is added, the server advertises it to its
+clients using `wl_registry.global`, and whenever an object is removed, this 
fact
+is advertised using
+[`wl_registry.global_remove`](https://wayland.freedesktop.org/docs/html/apa.html#protocol-spec-wl_registry-event-global_remove).
+
+See 
[wl_registry](https://wayland.freedesktop.org/docs/html/apa.html#protocol-spec-wl_registry)
+for the protocol description.
 
 ## Compositor
 
-The compositor is a global object, advertised at connect time.
+The compositor is a global object, advertised through the registry.
 
-See [wl_compositor](https://wayland.app/protocols/wayland#wl_compositor) for 
the
-protocol description.
+See 
[wl_compositor](https://wayland.freedesktop.org/docs/html/apa.html#protocol-spec-wl_compositor)
+for the protocol description.
 
 ## Surfaces
 
@@ -275,8 +306,8 @@
 
 ## Output
 
-An output is a global object, advertised at connect time or as it comes and
-goes.
+An output is a global object, advertised through the registry. Outputs may be
+added or removed during the lifetime of the server.
 
 See [wl_output](https://wayland.app/protocols/wayland#wl_output) for the
 protocol description.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/wayland-1.25.0/meson.build 
new/wayland-1.26.0/meson.build
--- old/wayland-1.25.0/meson.build      2026-03-19 17:03:08.000000000 +0100
+++ new/wayland-1.26.0/meson.build      2026-07-16 17:24:51.000000000 +0200
@@ -1,6 +1,6 @@
 project(
        'wayland', 'c',
-       version: '1.25.0',
+       version: '1.26.0',
        license: 'MIT',
        meson_version: '>= 0.64.0',
        default_options: [
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/wayland-1.25.0/protocol/wayland.xml 
new/wayland-1.26.0/protocol/wayland.xml
--- old/wayland-1.25.0/protocol/wayland.xml     2026-03-19 17:03:08.000000000 
+0100
+++ new/wayland-1.26.0/protocol/wayland.xml     2026-07-16 17:24:51.000000000 
+0200
@@ -100,11 +100,15 @@
 
     <event name="delete_id">
       <description summary="acknowledge object ID deletion">
-        This event is used internally by the object ID management
-        logic. When a client deletes an object that it had created,
-        the server will send this event to acknowledge that it has
-        seen the delete request. When the client receives this event,
-        it will know that it can safely reuse the object ID.
+        This event is used internally by the object ID management logic.
+
+        When the server stops using an object created by the client, the server
+        sends this event. In particular, after sending this event, the server
+        will no longer send any events that contain the object as the receiver
+        or as an argument.
+
+        When the client receives this event, it knows that it can reuse the
+        object ID.
       </description>
       <arg name="id" type="uint" summary="deleted object ID"/>
     </event>
@@ -140,7 +144,7 @@
         specified name as the identifier.
       </description>
       <arg name="name" type="uint" summary="unique numeric name of the 
object"/>
-      <arg name="id" type="new_id" summary="bounded object"/>
+      <arg name="id" type="new_id" summary="bound object"/>
     </request>
 
     <event name="global">
@@ -220,7 +224,7 @@
     </request>
   </interface>
 
-  <interface name="wl_shm_pool" version="2">
+  <interface name="wl_shm_pool" version="3">
     <description summary="a shared memory pool">
       The wl_shm_pool object encapsulates a piece of memory shared
       between the compositor and client.  Through the wl_shm_pool
@@ -231,6 +235,14 @@
       a surface or for many small buffers.
     </description>
 
+    <enum name="error" since="3">
+      <description summary="wl_shm_pool error values">
+        These errors can be emitted in response to wl_shm_pool requests.
+      </description>
+      <entry name="invalid_format" value="0" summary="buffer format is not 
known"/>
+      <entry name="invalid_stride" value="1" summary="invalid size or stride 
during buffer creation"/>
+    </enum>
+
     <request name="create_buffer">
       <description summary="create a buffer from the pool">
         Create a wl_buffer object from the pool.
@@ -280,7 +292,7 @@
     </request>
   </interface>
 
-  <interface name="wl_shm" version="2">
+  <interface name="wl_shm" version="3">
     <description summary="shared memory support">
       A singleton global object that provides support for shared
       memory.
@@ -293,12 +305,12 @@
       that can be used for buffers.
     </description>
 
-    <enum name="error">
+    <enum name="error" since="3">
       <description summary="wl_shm error values">
         These errors can be emitted in response to wl_shm requests.
       </description>
-      <entry name="invalid_format" value="0" summary="buffer format is not 
known"/>
-      <entry name="invalid_stride" value="1" summary="invalid size or stride 
during pool or buffer creation"/>
+      <entry name="invalid_format" value="0" summary="buffer format is not 
known" deprecated-since="3"/>
+      <entry name="invalid_stride" value="1" summary="invalid size or stride 
during pool creation"/>
       <entry name="invalid_fd" value="2" summary="mmapping the file descriptor 
failed"/>
     </enum>
 
@@ -331,7 +343,7 @@
       <entry name="bgrx4444" value="0x32315842" summary="16-bit BGRx format, 
[15:0] B:G:R:x 4:4:4:4 little endian"/>
       <entry name="argb4444" value="0x32315241" summary="16-bit ARGB format, 
[15:0] A:R:G:B 4:4:4:4 little endian"/>
       <entry name="abgr4444" value="0x32314241" summary="16-bit ABGR format, 
[15:0] A:B:G:R 4:4:4:4 little endian"/>
-      <entry name="rgba4444" value="0x32314152" summary="16-bit RBGA format, 
[15:0] R:G:B:A 4:4:4:4 little endian"/>
+      <entry name="rgba4444" value="0x32314152" summary="16-bit RGBA format, 
[15:0] R:G:B:A 4:4:4:4 little endian"/>
       <entry name="bgra4444" value="0x32314142" summary="16-bit BGRA format, 
[15:0] B:G:R:A 4:4:4:4 little endian"/>
       <entry name="xrgb1555" value="0x35315258" summary="16-bit xRGB format, 
[15:0] x:R:G:B 1:5:5:5 little endian"/>
       <entry name="xbgr1555" value="0x35314258" summary="16-bit xBGR 1555 
format, [15:0] x:B:G:R 1:5:5:5 little endian"/>
@@ -449,9 +461,9 @@
       <entry name="gr1616f" value="0x48205247" summary="[31:0] G:R 16:16 
little endian"/>
       <entry name="bgr161616f" value="0x48524742" summary="[47:0] B:G:R 
16:16:16 little endian"/>
       <entry name="r32f" value="0x46202052" summary="[31:0] R 32 little 
endian"/>
-      <entry name="gr3232f" value="0x46205247" summary="[63:0] R:G 32:32 
little endian"/>
-      <entry name="bgr323232f" value="0x46524742" summary="[95:0] R:G:B 
32:32:32 little endian"/>
-      <entry name="abgr32323232f" value="0x46384241" summary="[127:0] R:G:B:A 
32:32:32:32 little endian"/>
+      <entry name="gr3232f" value="0x46205247" summary="[63:0] G:R 32:32 
little endian"/>
+      <entry name="bgr323232f" value="0x46524742" summary="[95:0] B:G:R 
32:32:32 little endian"/>
+      <entry name="abgr32323232f" value="0x46384241" summary="[127:0] A:B:G:R 
32:32:32:32 little endian"/>
       <entry name="nv20" value="0x3032564e" summary="2x1 subsampled Cr:Cb 
plane"/>
       <entry name="nv30" value="0x3033564e" summary="non-subsampled Cr:Cb 
plane"/>
       <entry name="s010" value="0x30313053" summary="2x2 subsampled Cb (1) and 
Cr (2) planes 10 bits per channel"/>
@@ -463,6 +475,11 @@
       <entry name="s016" value="0x36313053" summary="2x2 subsampled Cb (1) and 
Cr (2) planes 16 bits per channel"/>
       <entry name="s216" value="0x36313253" summary="2x1 subsampled Cb (1) and 
Cr (2) planes 16 bits per channel"/>
       <entry name="s416" value="0x36313453" summary="non-subsampled Cb (1) and 
Cr (2) planes 16 bits per channel"/>
+      <entry name="xvuy2101010" value="0x30335958" summary="[31:0] x:Cr:Cb:Y 
2:10:10:10 little endian"/>
+      <entry name="p230" value="0x30333250" summary="2x1 subsampled Cr:Cb 
plane 10 bits per channel packed"/>
+      <entry name="t430" value="0x30333454"/>
+      <entry name="y8" value="0x59455247" summary="8-bit Y-only"/>
+      <entry name="xyyy2101010" value="0x34415059" summary="[31:0] x:Y2:Y1:Y0 
2:10:10:10 little endian"/>
     </enum>
 
     <request name="create_pool">
@@ -847,8 +864,8 @@
         acceptance, wl_data_source.cancelled may still be emitted afterwards
         if the drop destination does not accept any mime type.
 
-        However, this event might however not be received if the compositor
-        cancelled the drag-and-drop operation before this event could happen.
+        However, this event might not be received if the compositor cancelled
+        the drag-and-drop operation before this event could happen.
 
         Note that the data_source may still be used in the future and should
         not be destroyed here.
@@ -889,7 +906,7 @@
         The most recent action received is always the valid one. The chosen
         action may change alongside negotiation (e.g. an "ask" action can turn
         into a "move" operation), so the effects of the final action must
-        always be applied in wl_data_offer.dnd_finished.
+        always be applied in wl_data_source.dnd_finished.
 
         Clients can trigger cursor surface changes from this point, so
         they reflect the current action.
@@ -1984,7 +2001,7 @@
     </request>
    </interface>
 
-  <interface name="wl_seat" version="10">
+  <interface name="wl_seat" version="11">
     <description summary="group of input devices">
       A seat is a group of keyboards, pointer and touch devices. This
       object is published as a global during start up, or when such a
@@ -2098,7 +2115,7 @@
         shared across processes to refer to a specific wl_seat global.
 
         The name event is sent after binding to the seat global, and should be 
sent
-        before announcing capabilities. This event only sent once per seat 
object,
+        before announcing capabilities. This event is only sent once per seat 
object,
         and the name does not change over the lifetime of the wl_seat global.
 
         Compositors may re-use the same seat name if the wl_seat global is
@@ -2118,7 +2135,7 @@
 
   </interface>
 
-  <interface name="wl_pointer" version="10">
+  <interface name="wl_pointer" version="11">
     <description summary="pointer input device">
       The wl_pointer interface represents one or more input devices,
       such as mice, which control the pointer location and pointer_focus
@@ -2228,7 +2245,7 @@
       <description summary="pointer button event">
         Mouse button click and release notifications.
 
-        The location of the click is given by the last motion or
+        The location of the click is given by the last motion, warp or
         enter event.
         The time argument is a timestamp with millisecond
         granularity, with an undefined base.
@@ -2529,9 +2546,31 @@
       <arg name="direction" type="uint" enum="axis_relative_direction"
           summary="physical direction relative to axis motion"/>
     </event>
+
+    <!-- Version 11 additions -->
+
+    <event name="warp" since="11">
+      <description summary="pointer warp event">
+       Notification of pointer location change within a surface.
+
+       This location change is not due to events on the input device,
+       but because either the surface under the pointer was moved and
+       thus the relative position of the pointer changed, or because
+       the compositor changed the pointer position in response to an
+       event like pointer confinement being exited.
+
+       The arguments surface_x and surface_y are the location relative to
+       the focused surface.
+
+       This event must not occur in the same wl_pointer.frame as a
+       wl_pointer.enter or wl_pointer.motion event.
+      </description>
+      <arg name="surface_x" type="fixed" summary="surface-local x coordinate"/>
+      <arg name="surface_y" type="fixed" summary="surface-local y coordinate"/>
+    </event>
   </interface>
 
-  <interface name="wl_keyboard" version="10">
+  <interface name="wl_keyboard" version="11">
     <description summary="keyboard input device">
       The wl_keyboard interface represents one or more keyboards
       associated with a seat.
@@ -2712,7 +2751,7 @@
     </event>
   </interface>
 
-  <interface name="wl_touch" version="10">
+  <interface name="wl_touch" version="11">
     <description summary="touchscreen input device">
       The wl_touch interface represents a touchscreen
       associated with a seat.
@@ -2816,7 +2855,7 @@
         of the ellipse, while the minor axis length describes the shorter
         diameter. Major and minor are orthogonal and both are specified in
         surface-local coordinates. The center of the ellipse is always at the
-        touchpoint location as reported by wl_touch.down or wl_touch.move.
+        touchpoint location as reported by wl_touch.down or wl_touch.motion.
 
         This event is only sent by the compositor if the touch device supports
         shape reports. The client has to make reasonable assumptions about the
@@ -3335,12 +3374,20 @@
     </request>
   </interface>
 
-  <interface name="wl_fixes" version="1">
+  <interface name="wl_fixes" version="2">
     <description summary="wayland protocol fixes">
       This global fixes problems with other core-protocol interfaces that
       cannot be fixed in these interfaces themselves.
     </description>
 
+    <enum name="error">
+      <description summary="wl_fixes error values">
+        These errors can be emitted in response to wl_fixes requests.
+      </description>
+      <entry name="invalid_ack_remove" value="0"
+             summary="unknown global or the global is not removed"/>
+    </enum>
+
     <request name="destroy" type="destructor">
       <description summary="destroys this object"/>
     </request>
@@ -3360,6 +3407,36 @@
       <arg name="registry" type="object" interface="wl_registry"
            summary="the registry to destroy"/>
     </request>
+
+    <request name="ack_global_remove" since="2">
+      <description summary="acknowledge global removal">
+        Acknowledge the removal of the specified global.
+
+        If no global with the specified name exists or the global is not 
removed,
+        the wl_fixes.invalid_ack_remove protocol error will be posted.
+
+        Due to the Wayland protocol being asynchronous, the wl_global objects
+        cannot be destroyed immediately. For example, if a wl_global is removed
+        and a client attempts to bind that global around same time, it can
+        result in a protocol error due to an unknown global name in the bind
+        request.
+
+        In order to avoid crashing clients, the compositor should remove the
+        wl_global once it is guaranteed that no more bind requests will come.
+
+        The wl_fixes.ack_global_remove() request is used to signal to the
+        compositor that the client will not bind the given global anymore. 
After
+        all clients acknowledge the removal of the global, the compositor can
+        safely destroy it.
+
+        The client must call the wl_fixes.ack_global_remove() request in
+        response to a wl_registry.global_remove() event even if it did not bind
+        the corresponding global.
+      </description>
+      <arg name="registry" type="object" interface="wl_registry"
+           summary="the registry object"/>
+      <arg name="name" type="uint" summary="unique name of the global"/>
+    </request>
   </interface>
 
 </protocol>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/wayland-1.25.0/src/connection.c 
new/wayland-1.26.0/src/connection.c
--- old/wayland-1.25.0/src/connection.c 2026-03-19 17:03:08.000000000 +0100
+++ new/wayland-1.26.0/src/connection.c 2026-07-16 17:24:51.000000000 +0200
@@ -1547,7 +1547,6 @@
        struct argument_details arg;
        const char *signature = closure->message->signature;
        struct timespec tp;
-       unsigned int time;
        uint32_t nval;
        FILE *f;
        char *buffer;
@@ -1558,10 +1557,12 @@
                return;
 
        clock_gettime(CLOCK_REALTIME, &tp);
-       time = (tp.tv_sec * 1000000L) + (tp.tv_nsec / 1000);
-       fprintf(f, "%s[%7u.%03u] ",
+       fprintf(f, "%s[%02u:%02u:%02u.%06u] ",
                color ? WL_DEBUG_COLOR_GREEN : "",
-               time / 1000, time % 1000);
+               (unsigned) ((tp.tv_sec / 3600) % 24),
+               (unsigned) ((tp.tv_sec / 60) % 60),
+               (unsigned) (tp.tv_sec % 60),
+               (unsigned) (tp.tv_nsec / 1000));
 
 #if defined(HAVE_GETTID)
        if (include_tid < 0) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/wayland-1.25.0/src/scanner.c 
new/wayland-1.26.0/src/scanner.c
--- old/wayland-1.25.0/src/scanner.c    2026-03-19 17:03:08.000000000 +0100
+++ new/wayland-1.26.0/src/scanner.c    2026-07-16 17:24:51.000000000 +0200
@@ -189,7 +189,6 @@
        char *uppercase_name;
        struct wl_list arg_list;
        struct wl_list link;
-       int arg_count;
        int new_id_count;
        int type_index;
        int all_null;
@@ -890,7 +889,6 @@
                        arg->summary = xstrdup(summary);
 
                wl_list_insert(ctx->message->arg_list.prev, &arg->link);
-               ctx->message->arg_count++;
        } else if (strcmp(element_name, "enum") == 0) {
                if (name == NULL)
                        fail(&ctx->loc, "no enum name given");
@@ -1224,7 +1222,6 @@
                     "interface '%s' has method named destroy "
                     "but no destructor",
                     interface->name);
-               exit(EXIT_FAILURE);
        }
 
        if (!has_destroy && strcmp(interface->name, "wl_display") != 0) {
@@ -1630,6 +1627,10 @@
                m->all_null = 1;
                wl_list_for_each(a, &m->arg_list, link) {
                        length++;
+                       if (a->type == NEW_ID && !a->interface_name)
+                               // adds implicit string and uint arguments
+                               length += 2;
+
                        switch (a->type) {
                        case NEW_ID:
                        case OBJECT:
@@ -1867,9 +1868,15 @@
 
                m->type_index =
                        protocol->null_run_length + protocol->type_index;
-               protocol->type_index += m->arg_count;
 
                wl_list_for_each(a, &m->arg_list, link) {
+                       protocol->type_index++;
+                       if (a->type == NEW_ID && !a->interface_name) {
+                               // adds implicit string and uint arguments
+                               printf("\tNULL,\n\tNULL,\n");
+                               protocol->type_index += 2;
+                       }
+
                        switch (a->type) {
                        case NEW_ID:
                        case OBJECT:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/wayland-1.25.0/src/wayland-client.c 
new/wayland-1.26.0/src/wayland-client.c
--- old/wayland-1.25.0/src/wayland-client.c     2026-03-19 17:03:08.000000000 
+0100
+++ new/wayland-1.26.0/src/wayland-client.c     2026-07-16 17:24:51.000000000 
+0200
@@ -1577,7 +1577,6 @@
        const struct wl_message *message;
        struct wl_event_queue *queue;
        struct timespec tp;
-       unsigned int time;
        int num_zombie_fds;
 
        wl_connection_copy(display->connection, p, sizeof p);
@@ -1619,11 +1618,13 @@
 
                if (debug_client) {
                        clock_gettime(CLOCK_REALTIME, &tp);
-                       time = (tp.tv_sec * 1000000L) + (tp.tv_nsec / 1000);
-                       fprintf(stderr, "%s[%7u.%03u] %sdiscarded 
%s[%s]%s#%u%s.[event %d]%s"
+                       fprintf(stderr, "%s[%02u:%02u:%02u.%06u] %sdiscarded 
%s[%s]%s#%u%s.[event %d]%s"
                                "(%d fd, %d byte)\n",
                                debug_color ? WL_DEBUG_COLOR_GREEN : "",
-                               time / 1000, time % 1000,
+                               (unsigned) ((tp.tv_sec / 3600) % 24),
+                               (unsigned) ((tp.tv_sec / 60) % 60),
+                               (unsigned) (tp.tv_sec % 60),
+                               (unsigned) (tp.tv_nsec / 1000),
                                debug_color ? WL_DEBUG_COLOR_RED : "",
                                debug_color ? WL_DEBUG_COLOR_BLUE : "",
                                zombie ? "zombie" : "unknown",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/wayland-1.25.0/src/wayland-server-core.h 
new/wayland-1.26.0/src/wayland-server-core.h
--- old/wayland-1.25.0/src/wayland-server-core.h        2026-03-19 
17:03:08.000000000 +0100
+++ new/wayland-1.26.0/src/wayland-server-core.h        2026-07-16 
17:24:51.000000000 +0200
@@ -205,6 +205,9 @@
 int
 wl_display_add_socket_fd(struct wl_display *display, int sock_fd);
 
+int
+wl_display_remove_socket_fd(struct wl_display *display, int sock_fd);
+
 void
 wl_display_terminate(struct wl_display *display);
 
@@ -222,10 +225,13 @@
                                       size_t max_buffer_size);
 
 struct wl_client;
+struct wl_global;
 
 typedef void (*wl_global_bind_func_t)(struct wl_client *client, void *data,
                                      uint32_t version, uint32_t id);
 
+typedef void (*wl_global_withdrawn_func_t)(struct wl_global *global);
+
 uint32_t
 wl_display_get_serial(const struct wl_display *display);
 
@@ -254,6 +260,10 @@
 wl_global_remove(struct wl_global *global);
 
 void
+wl_global_set_withdrawn_listener(struct wl_global *global,
+                                wl_global_withdrawn_func_t func);
+
+void
 wl_global_destroy(struct wl_global *global);
 
 /** A filter function for wl_global objects
@@ -725,6 +735,11 @@
 void
 wl_protocol_logger_destroy(struct wl_protocol_logger *logger);
 
+void
+wl_fixes_handle_ack_global_remove(struct wl_resource *fixes_resource,
+                                 struct wl_resource *registry_resource,
+                                 uint32_t global_name);
+
 #ifdef  __cplusplus
 }
 #endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/wayland-1.25.0/src/wayland-server.c 
new/wayland-1.26.0/src/wayland-server.c
--- old/wayland-1.25.0/src/wayland-server.c     2026-03-19 17:03:08.000000000 
+0100
+++ new/wayland-1.26.0/src/wayland-server.c     2026-07-16 17:24:51.000000000 
+0200
@@ -115,15 +115,29 @@
        size_t max_buffer_size;
 };
 
+struct wl_registry {
+       struct wl_display *display;
+       struct wl_list offer_list;
+};
+
 struct wl_global {
        struct wl_display *display;
        const struct wl_interface *interface;
+       struct wl_list offer_list;
        uint32_t name;
        uint32_t version;
        void *data;
        wl_global_bind_func_t bind;
+       wl_global_withdrawn_func_t withdrawn;
        struct wl_list link;
-       bool removed;
+       bool unpublished;
+};
+
+struct wl_global_offer {
+       struct wl_list global_link; /**< in struct wl_global::offer_list */
+       struct wl_list registry_link; /**< in struct wl_registry::offer_list */
+       struct wl_resource *registry_resource;
+       struct wl_global *global;
 };
 
 struct wl_resource {
@@ -1048,7 +1062,8 @@
              const char *interface, uint32_t version, uint32_t id)
 {
        struct wl_global *global;
-       struct wl_display *display = resource->data;
+       struct wl_registry *registry = resource->data;
+       struct wl_display *display = registry->display;
 
        wl_list_for_each(global, &display->global_list, link)
                if (global->name == name)
@@ -1100,9 +1115,76 @@
 }
 
 static void
-unbind_resource(struct wl_resource *resource)
+wl_global_publish(struct wl_global *global,
+                 struct wl_resource *registry_resource)
+{
+       struct wl_global_offer *offer;
+       struct wl_registry *registry = registry_resource->data;
+
+       offer = zalloc(sizeof *offer);
+       if (offer == NULL) {
+               wl_resource_post_no_memory(registry_resource);
+               return;
+       }
+
+       offer->registry_resource = registry_resource;
+       offer->global = global;
+       wl_list_insert(&global->offer_list, &offer->global_link);
+       wl_list_insert(&registry->offer_list, &offer->registry_link);
+
+       wl_resource_post_event(registry_resource,
+                              WL_REGISTRY_GLOBAL,
+                              global->name,
+                              global->interface->name,
+                              global->version);
+}
+
+static void
+wl_global_offer_destroy(struct wl_global_offer *offer)
+{
+       wl_list_remove(&offer->global_link);
+       wl_list_remove(&offer->registry_link);
+       free(offer);
+}
+
+static void
+wl_global_offer_done(struct wl_global_offer *offer)
+{
+       struct wl_global *global = offer->global;
+
+       wl_global_offer_destroy(offer);
+
+       if (global->unpublished && global->withdrawn && 
wl_list_empty(&global->offer_list))
+               global->withdrawn(global);
+}
+
+static struct wl_global_offer *
+wl_registry_find_offer(struct wl_registry *registry,
+                      uint32_t global_name)
+{
+       struct wl_global_offer *offer;
+
+       wl_list_for_each(offer, &registry->offer_list, registry_link) {
+               if (offer->global->name == global_name)
+                       return offer;
+       }
+
+       return NULL;
+}
+
+static void
+unbind_registry_resource(struct wl_resource *resource)
 {
+       struct wl_registry *registry = resource->data;
+       struct wl_global_offer *offer;
+
+       while (!wl_list_empty(&registry->offer_list)) {
+               offer = wl_container_of(registry->offer_list.next, offer, 
registry_link);
+               wl_global_offer_done(offer);
+       }
+
        wl_list_remove(&resource->link);
+       free(registry);
 }
 
 static void
@@ -1112,6 +1194,7 @@
        struct wl_display *display = resource->data;
        struct wl_resource *registry_resource;
        struct wl_global *global;
+       struct wl_registry *registry;
 
        registry_resource =
                wl_resource_create(client, &wl_registry_interface, 1, id);
@@ -1120,20 +1203,25 @@
                return;
        }
 
+       registry = zalloc(sizeof *registry);
+       if (registry == NULL) {
+               wl_client_post_no_memory(client);
+               return;
+       }
+
+       registry->display = display;
+       wl_list_init(&registry->offer_list);
+
        wl_resource_set_implementation(registry_resource,
                                       &registry_interface,
-                                      display, unbind_resource);
+                                      registry, unbind_registry_resource);
 
        wl_list_insert(&display->registry_resource_list,
                       &registry_resource->link);
 
        wl_list_for_each(global, &display->global_list, link)
-               if (wl_global_is_visible(client, global) && !global->removed)
-                       wl_resource_post_event(registry_resource,
-                                              WL_REGISTRY_GLOBAL,
-                                              global->name,
-                                              global->interface->name,
-                                              global->version);
+               if (wl_global_is_visible(client, global) && 
!global->unpublished)
+                       wl_global_publish(global, registry_resource);
 }
 
 static const struct wl_display_interface display_interface = {
@@ -1270,6 +1358,7 @@
        if (s->fd_lock >= 0)
                close(s->fd_lock);
 
+       wl_list_remove(&s->link);
        free(s);
 }
 
@@ -1284,6 +1373,7 @@
 
        s->fd = -1;
        s->fd_lock = -1;
+       wl_list_init(&s->link);
 
        return s;
 }
@@ -1399,20 +1489,30 @@
        global->version = version;
        global->data = data;
        global->bind = bind;
-       global->removed = false;
+       global->withdrawn = NULL;
+       global->unpublished = false;
        wl_list_insert(display->global_list.prev, &global->link);
+       wl_list_init(&global->offer_list);
 
        wl_list_for_each(resource, &display->registry_resource_list, link)
                if (wl_global_is_visible(resource->client, global))
-                       wl_resource_post_event(resource,
-                                              WL_REGISTRY_GLOBAL,
-                                              global->name,
-                                              global->interface->name,
-                                              global->version);
+                       wl_global_publish(global, resource);
 
        return global;
 }
 
+static void
+wl_global_unpublish(struct wl_global *global)
+{
+       struct wl_global_offer *offer;
+
+       wl_list_for_each(offer, &global->offer_list, global_link)
+               wl_resource_post_event(offer->registry_resource,
+                                      WL_REGISTRY_GLOBAL_REMOVE, global->name);
+
+       global->unpublished = true;
+}
+
 /** Remove the global
  *
  * \param global The Wayland global.
@@ -1420,45 +1520,93 @@
  * Broadcast a global remove event to all clients without destroying the
  * global. This function can only be called once per global.
  *
- * wl_global_destroy() removes the global and immediately destroys it. On
- * the other end, this function only removes the global, allowing clients
- * that have not yet received the global remove event to continue to bind to
- * it.
- *
  * This can be used by compositors to mitigate clients being disconnected
- * because a global has been added and removed too quickly. Compositors can 
call
- * wl_global_remove(), then wait an implementation-defined amount of time, then
- * call wl_global_destroy(). Note that the destruction of a global is still
- * racy, since clients have no way to acknowledge that they received the remove
- * event.
+ * because a global has been added and removed too quickly.
+ *
+ * Due to the Wayland protocol being asynchronous, the wl_global objects
+ * cannot be destroyed immediately. For example, if a wl_global is destroyed
+ * and a client attempts to bind that global around same time, it can
+ * result in a protocol error due to an unknown global name in the bind 
request.
+ *
+ * In order to avoid crashing clients, the compositor should destroy the
+ * wl_global once it is guaranteed that no more bind requests will come.
+ *
+ * The recommended way to destroy globals is as follows:
+ *
+ * - the compositor registers a callback using the 
wl_global_set_withdrawn_listener()
+ *   function, which will be called when it is safe to call 
wl_global_destroy();
+ * - the compositor calls wl_global_remove(). This will broadcast
+ *   wl_registry.global_remove events to all clients;
+ * - upon receiving a wl_registry.global_remove event, a client must
+ *   reply to it by calling the wl_fixes.ack_global_remove() request. The
+ *   client must call the wl_fixes.ack_global_remove() request even if it
+ *   did not bind the global;
+ * - the compositor will call the wl_fixes_handle_ack_global_remove() function 
when
+ *   it receives the wl_fixes.ack_global_remove() request from the client;
+ * - after all clients have acknowledged the global removal, the "withdrawn"
+ *   callback will be called to notify the compositor that the
+ *   wl_global_destroy() function can be called now.
  *
+ * \sa wl_global_set_withdrawn_listener
+ * \sa wl_fixes_handle_ack_global_remove
  * \since 1.17.90
  */
 WL_EXPORT void
 wl_global_remove(struct wl_global *global)
 {
-       struct wl_display *display = global->display;
-       struct wl_resource *resource;
-
-       if (global->removed)
+       if (global->unpublished)
                wl_abort("wl_global_remove: called twice on the same "
                         "global '%s#%"PRIu32"'", global->interface->name,
                         global->name);
 
-       wl_list_for_each(resource, &display->registry_resource_list, link)
-               if (wl_global_is_visible(resource->client, global))
-                       wl_resource_post_event(resource, 
WL_REGISTRY_GLOBAL_REMOVE,
-                                              global->name);
+       wl_global_unpublish(global);
 
-       global->removed = true;
+       if (global->withdrawn && wl_list_empty(&global->offer_list))
+               global->withdrawn(global);
+}
+
+/** Set the withdrawn callback.
+ *
+ * \param global The Wayland global.
+ * \param func The withdrawn callback.
+ *
+ * The withdrawn callback notifies the compositor that the global can be
+ * safely destroyed by calling wl_global_destroy(). The callback will be called
+ * in the following cases:
+ *
+ * - immediately by wl_global_remove(), if there are no registeries where the
+ *   global was announced;
+ * - or some time later after wl_global_remove(), due to either receiving the
+ *   last wl_fixes_handle_ack_global_remove() or getting the last wl_registry
+ *   where the global was announced destroyed.
+ *
+ * The withdrawn callback will never be called without prior 
wl_global_remove().
+ *
+ * \sa wl_fixes_handle_ack_global_remove
+ * \since 1.26
+ */
+WL_EXPORT void
+wl_global_set_withdrawn_listener(struct wl_global *global,
+                                wl_global_withdrawn_func_t func)
+{
+       global->withdrawn = func;
 }
 
 WL_EXPORT void
 wl_global_destroy(struct wl_global *global)
 {
-       if (!global->removed)
-               wl_global_remove(global);
+       struct wl_global_offer *offer;
+
+       if (!global->unpublished)
+               wl_global_unpublish(global);
+
        wl_list_remove(&global->link);
+
+       while (!wl_list_empty(&global->offer_list)) {
+               offer = wl_container_of(global->offer_list.next, offer, 
global_link);
+               wl_global_offer_destroy(offer);
+       }
+
        free(global);
 }
 
@@ -1894,7 +2042,8 @@
  * with both bind() and listen() already called.
  *
  * On success, the socket fd ownership is transferred to libwayland:
- * libwayland will close the socket when the display is destroyed.
+ * libwayland will close the socket when the display is destroyed or when
+ * wl_display_remove_socket_fd() is called.
  *
  * \memberof wl_display
  */
@@ -1930,6 +2079,37 @@
        return 0;
 }
 
+/** Remove a socket fd from the Wayland display.
+ *
+ * \param display Wayland display from which the socket should be removed.
+ * \param sock_fd The socket file descriptor to be removed.
+ * \return 0 if success. -1 if failed.
+ *
+ * Remove a socket fd previously added via wl_display_add_socket_fd().
+ *
+ * \memberof wl_display
+ * \since 1.25.90
+ */
+WL_EXPORT int
+wl_display_remove_socket_fd(struct wl_display *display, int sock_fd)
+{
+       struct wl_socket *s;
+       bool found;
+
+       found = false;
+       wl_list_for_each(s, &display->socket_list, link) {
+               if (s->fd == sock_fd) {
+                       found = true;
+                       break;
+               }
+       }
+       if (!found)
+               return -1;
+
+       wl_socket_destroy(s);
+       return 0;
+}
+
 /** Add a socket to Wayland display for the clients to connect.
  *
  * \param display Wayland display to which the socket should be added.
@@ -2709,6 +2889,47 @@
        wl_global_destroy(global);
 }
 
+/** Acknowledge global removal by a client
+ *
+ * \param fixes_resource The wl_fixes resource.
+ * \param registry_resource The wl_registry resource.
+ * \param global_name The unique id of the global.
+ *
+ * The compositor should call this function from the wl_fixes.ack_global_remove
+ * request implementation.
+ *
+ * libwayland-server automatically takes care of the implied ack-remove due
+ * to client disconnection or explicit wl_resource_destroy() of the wl_registry
+ * resource.
+ *
+ * \sa wl_global_remove
+ * \sa wl_global_set_withdrawn_listener
+ * \since 1.26
+ */
+WL_EXPORT void
+wl_fixes_handle_ack_global_remove(struct wl_resource *fixes_resource,
+                                 struct wl_resource *registry_resource,
+                                 uint32_t global_name)
+{
+       struct wl_global_offer *offer;
+       struct wl_registry *registry = registry_resource->data;
+
+       offer = wl_registry_find_offer(registry, global_name);
+       if (!offer) {
+               wl_resource_post_error(fixes_resource, 
WL_FIXES_ERROR_INVALID_ACK_REMOVE,
+                                      "the given registry did not announce 
global %u", global_name);
+               return;
+       }
+
+       if (!offer->global->unpublished) {
+               wl_resource_post_error(fixes_resource, 
WL_FIXES_ERROR_INVALID_ACK_REMOVE,
+                                      "global %u is not removed", global_name);
+               return;
+       }
+
+       wl_global_offer_done(offer);
+}
+
 /** \endcond */
 
 /* Functions at the end of this file are deprecated.  Instead of adding new
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/wayland-1.25.0/src/wayland-util.c 
new/wayland-1.26.0/src/wayland-util.c
--- old/wayland-1.25.0/src/wayland-util.c       2026-03-19 17:03:08.000000000 
+0100
+++ new/wayland-1.26.0/src/wayland-util.c       2026-07-16 17:24:51.000000000 
+0200
@@ -424,10 +424,12 @@
        union map_entry entry, *start;
        size_t count;
 
-       start = (union map_entry *) entries->data;
-       count = entries->size / sizeof(union map_entry);
+       for (size_t idx = 0; ; idx++) {
+               count = entries->size / sizeof(union map_entry);
+               if (idx >= count)
+                       break;
 
-       for (size_t idx = 0; idx < count; idx++) {
+               start = (union map_entry *) entries->data;
                entry = start[idx];
                if (entry.data && !map_entry_is_free(entry)) {
                        ret = func(map_entry_get_data(entry), data, 
map_entry_get_flags(entry));
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/wayland-1.25.0/tests/data/small-code-core.c 
new/wayland-1.26.0/tests/data/small-code-core.c
--- old/wayland-1.25.0/tests/data/small-code-core.c     2026-03-19 
17:03:08.000000000 +0100
+++ new/wayland-1.26.0/tests/data/small-code-core.c     2026-07-16 
17:24:51.000000000 +0200
@@ -35,6 +35,8 @@
 
 static const struct wl_interface *small_test_types[] = {
        NULL,
+       NULL,
+       NULL,
        &intf_not_here_interface,
        NULL,
        NULL,
@@ -46,7 +48,7 @@
 
 static const struct wl_message intf_A_requests[] = {
        { "rq1", "sun", small_test_types + 0 },
-       { "rq2", "nsiufho", small_test_types + 1 },
+       { "rq2", "nsiufho", small_test_types + 3 },
        { "destroy", "", small_test_types + 0 },
 };
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/wayland-1.25.0/tests/data/small-code.c 
new/wayland-1.26.0/tests/data/small-code.c
--- old/wayland-1.25.0/tests/data/small-code.c  2026-03-19 17:03:08.000000000 
+0100
+++ new/wayland-1.26.0/tests/data/small-code.c  2026-07-16 17:24:51.000000000 
+0200
@@ -35,6 +35,8 @@
 
 static const struct wl_interface *small_test_types[] = {
        NULL,
+       NULL,
+       NULL,
        &intf_not_here_interface,
        NULL,
        NULL,
@@ -46,7 +48,7 @@
 
 static const struct wl_message intf_A_requests[] = {
        { "rq1", "sun", small_test_types + 0 },
-       { "rq2", "nsiufho", small_test_types + 1 },
+       { "rq2", "nsiufho", small_test_types + 3 },
        { "destroy", "", small_test_types + 0 },
 };
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/wayland-1.25.0/tests/data/small-private-code.c 
new/wayland-1.26.0/tests/data/small-private-code.c
--- old/wayland-1.25.0/tests/data/small-private-code.c  2026-03-19 
17:03:08.000000000 +0100
+++ new/wayland-1.26.0/tests/data/small-private-code.c  2026-07-16 
17:24:51.000000000 +0200
@@ -45,6 +45,8 @@
 
 static const struct wl_interface *small_test_types[] = {
        NULL,
+       NULL,
+       NULL,
        &intf_not_here_interface,
        NULL,
        NULL,
@@ -56,7 +58,7 @@
 
 static const struct wl_message intf_A_requests[] = {
        { "rq1", "sun", small_test_types + 0 },
-       { "rq2", "nsiufho", small_test_types + 1 },
+       { "rq2", "nsiufho", small_test_types + 3 },
        { "destroy", "", small_test_types + 0 },
 };
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/wayland-1.25.0/tests/display-test.c 
new/wayland-1.26.0/tests/display-test.c
--- old/wayland-1.25.0/tests/display-test.c     2026-03-19 17:03:08.000000000 
+0100
+++ new/wayland-1.26.0/tests/display-test.c     2026-07-16 17:24:51.000000000 
+0200
@@ -51,6 +51,63 @@
 #include "tests-server-protocol.h"
 #include "tests-client-protocol.h"
 
+static void
+registry_handle_global_noop(void *data,
+                           struct wl_registry *registry,
+                           uint32_t id, const char *interface,
+                           uint32_t ver)
+{
+}
+
+static void
+registry_handle_global_remove_noop(void *data,
+                                  struct wl_registry *registry,
+                                  uint32_t id)
+{
+}
+
+static void
+fixes_destroy(struct wl_client *client,
+             struct wl_resource *resource)
+{
+       wl_resource_destroy(resource);
+}
+
+static void
+fixes_destroy_registry(struct wl_client *client,
+                      struct wl_resource *resource,
+                      struct wl_resource *registry)
+{
+       wl_resource_destroy(registry);
+}
+
+static void
+fixes_ack_global_remove(struct wl_client *client,
+                       struct wl_resource *resource,
+                       struct wl_resource *registry,
+                       uint32_t global_id)
+{
+       wl_fixes_handle_ack_global_remove(resource, registry, global_id);
+}
+
+static const struct wl_fixes_interface fixes_implementation = {
+       .destroy = fixes_destroy,
+       .destroy_registry = fixes_destroy_registry,
+       .ack_global_remove = fixes_ack_global_remove,
+};
+
+static void
+bind_fixes(struct wl_client *client,
+          void *data,
+          uint32_t version,
+          uint32_t id)
+{
+       struct wl_resource *resource;
+
+       resource = wl_resource_create(client, &wl_fixes_interface, version, id);
+       wl_resource_set_implementation(resource, &fixes_implementation, NULL, 
NULL);
+}
+
 struct display_destroy_listener {
        struct wl_listener listener;
        int done;
@@ -1692,6 +1749,172 @@
 
        wl_global_destroy(global);
 
+       display_destroy(d);
+}
+
+static void
+registry_ack_global_remove_handle_global_remove(void *data,
+                                               struct wl_registry *registry,
+                                               uint32_t id)
+{
+       struct client *client = data;
+
+       wl_fixes_ack_global_remove(client->wl_fixes, registry, id);
+}
+
+static struct wl_registry_listener registry_ack_global_remove_listener = {
+       .global = registry_handle_global_noop,
+       .global_remove = registry_ack_global_remove_handle_global_remove,
+};
+
+static void
+ack_global_remove_client(void *data)
+{
+       struct client *c = client_connect();
+       struct wl_registry *registry;
+       struct wl_registry_listener *registry_listener = data;
+       int ret;
+
+       registry = wl_display_get_registry(c->wl_display);
+       wl_registry_add_listener(registry,
+                                registry_listener,
+                                c);
+
+       ret = wl_display_roundtrip(c->wl_display);
+       assert(ret >= 0);
+
+       /* yield the control back to the compositor so it can remove
+        * the global */
+       assert(stop_display(c, 1) >= 0);
+
+       /* check if there are any global_remove events */
+       ret = wl_display_roundtrip(c->wl_display);
+       assert(ret >= 0);
+
+       /* yield the control back to the compositor so it can check
+        * whether the global is withdrawn */
+       assert(stop_display(c, 1) >= 0);
+
+       wl_registry_destroy(registry);
+
+       client_disconnect(c);
+}
+
+static void
+mark_global_withdrawn(struct wl_global *global)
+{
+       bool *withdrawn = wl_global_get_user_data(global);
+
+       *withdrawn = true;
+}
+
+TEST(ack_global_remove)
+{
+       struct display *d;
+       struct wl_global *seat;
+       struct wl_global *fixes;
+       bool withdrawn = false;
+
+       d = display_create();
+
+       fixes = wl_global_create(d->wl_display, &wl_fixes_interface,
+                                2, NULL, bind_fixes);
+
+       seat = wl_global_create(d->wl_display, &wl_seat_interface,
+                               1, &withdrawn, NULL);
+
+       wl_global_set_withdrawn_listener(seat, mark_global_withdrawn);
+
+       client_create(d, ack_global_remove_client,
+                     &registry_ack_global_remove_listener);
+
+       display_run(d);
+       assert(!withdrawn);
+
+       wl_global_remove(seat);
+
+       /* the global will be marked as withdrawn after the client
+        * acknowledges the wl_registry.global_remove event */
+       display_resume(d);
+       assert(withdrawn);
+
+       /* the global will be still marked as withdrawn even after
+        * the client disconnects */
+       display_resume(d);
+       assert(withdrawn);
+
+       wl_global_destroy(seat);
+       wl_global_destroy(fixes);
+
+       display_destroy(d);
+}
+
+static struct wl_registry_listener registry_no_ack_global_remove_listener = {
+       .global = registry_handle_global_noop,
+       .global_remove = registry_handle_global_remove_noop,
+};
+
+TEST(no_ack_global_remove)
+{
+       struct display *d;
+       struct wl_global *seat;
+       struct wl_global *fixes;
+       bool withdrawn = false;
+
+       d = display_create();
+
+       fixes = wl_global_create(d->wl_display, &wl_fixes_interface,
+                                2, NULL, bind_fixes);
+
+       seat = wl_global_create(d->wl_display, &wl_seat_interface,
+                               1, &withdrawn, NULL);
+
+       wl_global_set_withdrawn_listener(seat, mark_global_withdrawn);
+
+       client_create(d, ack_global_remove_client,
+                     &registry_no_ack_global_remove_listener);
+
+       display_run(d);
+       assert(!withdrawn);
+
+       wl_global_remove(seat);
+
+       /* if the client does not ack the wl_registry.global_remove event,
+        * the global will not be marked as withdrawn */
+       display_resume(d);
+       assert(!withdrawn);
+
+       /* when the client disconnects, the wl_registry.global_remove will
+        * be implicitly acknowledged and the global can be destroyed then */
+       display_resume(d);
+       assert(withdrawn);
+
+       wl_global_destroy(seat);
+       wl_global_destroy(fixes);
+
+       display_destroy(d);
+}
+
+TEST(global_remove_without_clients)
+{
+       struct display *d;
+       struct wl_global *global;
+       bool withdrawn = false;
+
+       d = display_create();
+
+       global = wl_global_create(d->wl_display, &wl_seat_interface,
+                                 1, &withdrawn, NULL);
+
+       wl_global_set_withdrawn_listener(global, mark_global_withdrawn);
+
+       /* if there are no clients at all, the global can be destroyed
+        * immediately */
+       wl_global_remove(global);
+       assert(withdrawn);
+
+       wl_global_destroy(global);
+
        display_destroy(d);
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/wayland-1.25.0/tests/test-compositor.c 
new/wayland-1.26.0/tests/test-compositor.c
--- old/wayland-1.25.0/tests/test-compositor.c  2026-03-19 17:03:08.000000000 
+0100
+++ new/wayland-1.26.0/tests/test-compositor.c  2026-07-16 17:24:51.000000000 
+0200
@@ -491,14 +491,15 @@
 {
        struct client *c = data;
 
-       if (strcmp(intf, "test") != 0)
-               return;
-
-       c->tc = wl_registry_bind(registry, id, &test_compositor_interface, ver);
-       assert(c->tc && "Failed binding to registry");
-
-       wl_proxy_add_listener((struct wl_proxy *) c->tc,
-                             (void *) &tc_listener, c);
+       if (strcmp(intf, "test") == 0) {
+               c->tc = wl_registry_bind(registry, id, 
&test_compositor_interface, ver);
+               assert(c->tc && "Failed binding to registry");
+
+               wl_proxy_add_listener((struct wl_proxy *) c->tc,
+                                     (void *) &tc_listener, c);
+       } else if (strcmp(intf, wl_fixes_interface.name) == 0) {
+               c->wl_fixes = wl_registry_bind(registry, id, 
&wl_fixes_interface, 2);
+       }
 }
 
 static const struct wl_registry_listener registry_listener =
@@ -524,6 +525,9 @@
        wl_display_roundtrip(c->wl_display);
        assert(c->tc);
 
+       if (c->wl_fixes) {
+               wl_fixes_destroy_registry(c->wl_fixes, reg);
+       }
        wl_registry_destroy(reg);
 
        return c;
@@ -556,6 +560,10 @@
        /* check for errors */
        check_error(c->wl_display);
 
+       if (c->wl_fixes) {
+               wl_fixes_destroy(c->wl_fixes);
+       }
+
        wl_proxy_destroy((struct wl_proxy *) c->tc);
        wl_display_disconnect(c->wl_display);
        free(c);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/wayland-1.25.0/tests/test-compositor.h 
new/wayland-1.26.0/tests/test-compositor.h
--- old/wayland-1.25.0/tests/test-compositor.h  2026-03-19 17:03:08.000000000 
+0100
+++ new/wayland-1.26.0/tests/test-compositor.h  2026-07-16 17:24:51.000000000 
+0200
@@ -66,6 +66,7 @@
  * filled. */
 struct client {
        struct wl_display *wl_display;
+       struct wl_fixes *wl_fixes;
        struct test_compositor *tc;
 
        atomic_bool display_stopped;

Reply via email to