Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package wlroots for openSUSE:Factory checked in at 2026-03-22 14:12:03 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/wlroots (Old) and /work/SRC/openSUSE:Factory/.wlroots.new.8177 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "wlroots" Sun Mar 22 14:12:03 2026 rev:40 rq:1341613 version:0.19.3 Changes: -------- --- /work/SRC/openSUSE:Factory/wlroots/wlroots.changes 2026-03-12 22:25:36.774466513 +0100 +++ /work/SRC/openSUSE:Factory/.wlroots.new.8177/wlroots.changes 2026-03-22 14:13:11.355867990 +0100 @@ -1,0 +2,26 @@ +Fri Mar 20 22:13:53 UTC 2026 - zeus <[email protected]> + +- Update to 0.19.3 + * backend/libinput: fix build with libinput 1.31 + * backend/libinput: add support for LIBINPUT_SWITCH_KEYPAD_SLIDE + * image_capture_source/output: Update constraints on enable + * Add "const" to eliminate "error: initialization discards ‘const’ qualifier from pointer target type" + * wlr_virtual_pointer: Set axis source on all axis + * render/allocator: add missing wlr_buffer_finish() in destroy impls + * backend/drm: Close non-master drm fd on failure + * tinywl: fix duplicate object files passed to linker + * backend/libinput: guard against new enum entries + * render/vulkan: introduce buffer_import_sync_file() + * render/vulkan: take render pass in vulkan_sync_render_buffer() + * render/vulkan: fix missing DMA-BUF implicit read fence for textures + * render/vulkan: introduce buffer_export_sync_file() + * render/vulkan: add "acquire" to vulkan_sync_foreign_texture() + * render/vulkan: fix missing DMA-BUF implicit write fence for render buffer + * build: bump version to 0.19.3 + * ci: update dalligi upstream repo + * xwayland: fix memory leak on pipe() failure + * backend/session: respond to event hangup or error + +- Remove compiler workarounds + +------------------------------------------------------------------- Old: ---- wlroots-0.19.2.tar.gz wlroots-0.19.2.tar.gz.sig New: ---- wlroots-0.19.3.tar.gz wlroots-0.19.3.tar.gz.sig ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ wlroots.spec ++++++ --- /var/tmp/diff_new_pack.nj6kp0/_old 2026-03-22 14:13:11.967893157 +0100 +++ /var/tmp/diff_new_pack.nj6kp0/_new 2026-03-22 14:13:11.967893157 +0100 @@ -18,7 +18,7 @@ %global ver_suffix 0.19 %global sover 0_19 -%global patch_ver 2 +%global patch_ver 3 %global libname libwlroots-%{sover} %bcond_without drm_backend %bcond_without libinput_backend @@ -103,7 +103,6 @@ %autosetup -p1 %build -export CFLAGS="%{optflags} -I/usr/include/wayland -Wno-redundant-decls -Wno-error=switch" %meson \ "-Dbackends=[ %{?with_drm_backend:'drm',} ++++++ wlroots-0.19.2.tar.gz -> wlroots-0.19.3.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wlroots-0.19.2/.gitlab-ci.yml new/wlroots-0.19.3/.gitlab-ci.yml --- old/wlroots-0.19.2/.gitlab-ci.yml 2025-10-22 00:21:53.000000000 +0200 +++ new/wlroots-0.19.3/.gitlab-ci.yml 2026-03-19 20:13:09.000000000 +0100 @@ -1,4 +1,4 @@ -include: https://git.sr.ht/~emersion/dalligi/blob/master/templates/multi.yml +include: https://gitlab.freedesktop.org/emersion/dalligi/-/raw/master/templates/multi.yml alpine: extends: .dalligi pages: true diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wlroots-0.19.2/backend/drm/drm.c new/wlroots-0.19.3/backend/drm/drm.c --- old/wlroots-0.19.2/backend/drm/drm.c 2025-10-22 00:21:53.000000000 +0200 +++ new/wlroots-0.19.3/backend/drm/drm.c 2026-03-19 20:13:09.000000000 +0100 @@ -2085,6 +2085,7 @@ if (drmIsMaster(fd) && drmDropMaster(fd) < 0) { wlr_log_errno(WLR_ERROR, "Failed to drop master"); + close(fd); return -1; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wlroots-0.19.2/backend/libinput/events.c new/wlroots-0.19.3/backend/libinput/events.c --- old/wlroots-0.19.2/backend/libinput/events.c 2025-10-22 00:21:53.000000000 +0200 +++ new/wlroots-0.19.3/backend/libinput/events.c 2026-03-19 20:13:09.000000000 +0100 @@ -249,3 +249,15 @@ break; } } + +bool button_state_from_libinput(enum libinput_button_state state, enum wlr_button_state *out) { + switch (state) { + case LIBINPUT_BUTTON_STATE_RELEASED: + *out = WLR_BUTTON_RELEASED; + return true; + case LIBINPUT_BUTTON_STATE_PRESSED: + *out = WLR_BUTTON_PRESSED; + return true; + } + return false; +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wlroots-0.19.2/backend/libinput/keyboard.c new/wlroots-0.19.3/backend/libinput/keyboard.c --- old/wlroots-0.19.2/backend/libinput/keyboard.c 2025-10-22 00:21:53.000000000 +0200 +++ new/wlroots-0.19.3/backend/libinput/keyboard.c 2026-03-19 20:13:09.000000000 +0100 @@ -2,6 +2,7 @@ #include <libinput.h> #include <stdlib.h> #include <wlr/interfaces/wlr_keyboard.h> +#include <wlr/util/log.h> #include "backend/libinput.h" struct wlr_libinput_input_device *device_from_keyboard( @@ -30,6 +31,18 @@ libinput_device_led_update(dev->handle, 0); } +static bool key_state_from_libinput(enum libinput_key_state state, enum wl_keyboard_key_state *out) { + switch (state) { + case LIBINPUT_KEY_STATE_RELEASED: + *out = WL_KEYBOARD_KEY_STATE_RELEASED; + return true; + case LIBINPUT_KEY_STATE_PRESSED: + *out = WL_KEYBOARD_KEY_STATE_PRESSED; + return true; + } + return false; +} + void handle_keyboard_key(struct libinput_event *event, struct wlr_keyboard *kb) { struct libinput_event_keyboard *kbevent = @@ -39,13 +52,9 @@ .keycode = libinput_event_keyboard_get_key(kbevent), .update_state = true, }; - switch (libinput_event_keyboard_get_key_state(kbevent)) { - case LIBINPUT_KEY_STATE_RELEASED: - wlr_event.state = WL_KEYBOARD_KEY_STATE_RELEASED; - break; - case LIBINPUT_KEY_STATE_PRESSED: - wlr_event.state = WL_KEYBOARD_KEY_STATE_PRESSED; - break; + if (!key_state_from_libinput(libinput_event_keyboard_get_key_state(kbevent), &wlr_event.state)) { + wlr_log(WLR_DEBUG, "Unhandled libinput key state"); + return; } wlr_keyboard_notify_key(kb, &wlr_event); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wlroots-0.19.2/backend/libinput/meson.build new/wlroots-0.19.3/backend/libinput/meson.build --- old/wlroots-0.19.2/backend/libinput/meson.build 2025-10-22 00:21:53.000000000 +0200 +++ new/wlroots-0.19.3/backend/libinput/meson.build 2026-03-19 20:13:09.000000000 +0100 @@ -29,3 +29,7 @@ wlr_deps += libinput internal_config.set10('HAVE_LIBINPUT_BUSTYPE', libinput.version().version_compare('>=1.26.0')) +internal_config.set10( + 'HAVE_LIBINPUT_SWITCH_KEYPAD_SLIDE', + libinput.version().version_compare('>=1.30.901') +) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wlroots-0.19.2/backend/libinput/pointer.c new/wlroots-0.19.3/backend/libinput/pointer.c --- old/wlroots-0.19.2/backend/libinput/pointer.c 2025-10-22 00:21:53.000000000 +0200 +++ new/wlroots-0.19.3/backend/libinput/pointer.c 2026-03-19 20:13:09.000000000 +0100 @@ -1,6 +1,7 @@ #include <assert.h> #include <libinput.h> #include <wlr/interfaces/wlr_pointer.h> +#include <wlr/util/log.h> #include "backend/libinput.h" const struct wlr_pointer_impl libinput_pointer_impl = { @@ -52,6 +53,38 @@ wl_signal_emit_mutable(&pointer->events.frame, pointer); } +static bool pointer_button_state_from_libinput(enum libinput_button_state state, + enum wl_pointer_button_state *out) { + switch (state) { + case LIBINPUT_BUTTON_STATE_PRESSED: + *out = WL_POINTER_BUTTON_STATE_PRESSED; + return true; + case LIBINPUT_BUTTON_STATE_RELEASED: + *out = WL_POINTER_BUTTON_STATE_RELEASED; + return true; + } + return false; +} + +static bool axis_source_from_libinput(enum libinput_pointer_axis_source source, + enum wl_pointer_axis_source *out) { + switch (source) { + case LIBINPUT_POINTER_AXIS_SOURCE_WHEEL: + *out = WL_POINTER_AXIS_SOURCE_WHEEL; + return true; + case LIBINPUT_POINTER_AXIS_SOURCE_FINGER: + *out = WL_POINTER_AXIS_SOURCE_FINGER; + return true; + case LIBINPUT_POINTER_AXIS_SOURCE_CONTINUOUS: + *out = WL_POINTER_AXIS_SOURCE_CONTINUOUS; + return true; + case LIBINPUT_POINTER_AXIS_SOURCE_WHEEL_TILT: + *out = WL_POINTER_AXIS_SOURCE_WHEEL_TILT; + return true; + } + return false; +} + void handle_pointer_button(struct libinput_event *event, struct wlr_pointer *pointer) { struct libinput_event_pointer *pevent = @@ -61,13 +94,10 @@ .time_msec = usec_to_msec(libinput_event_pointer_get_time_usec(pevent)), .button = libinput_event_pointer_get_button(pevent), }; - switch (libinput_event_pointer_get_button_state(pevent)) { - case LIBINPUT_BUTTON_STATE_PRESSED: - wlr_event.state = WL_POINTER_BUTTON_STATE_PRESSED; - break; - case LIBINPUT_BUTTON_STATE_RELEASED: - wlr_event.state = WL_POINTER_BUTTON_STATE_RELEASED; - break; + if (!pointer_button_state_from_libinput(libinput_event_pointer_get_button_state(pevent), + &wlr_event.state)) { + wlr_log(WLR_DEBUG, "Unhandled libinput button state"); + return; } wlr_pointer_notify_button(pointer, &wlr_event); wl_signal_emit_mutable(&pointer->events.frame, pointer); @@ -81,19 +111,9 @@ .pointer = pointer, .time_msec = usec_to_msec(libinput_event_pointer_get_time_usec(pevent)), }; - switch (libinput_event_pointer_get_axis_source(pevent)) { - case LIBINPUT_POINTER_AXIS_SOURCE_WHEEL: - wlr_event.source = WL_POINTER_AXIS_SOURCE_WHEEL; - break; - case LIBINPUT_POINTER_AXIS_SOURCE_FINGER: - wlr_event.source = WL_POINTER_AXIS_SOURCE_FINGER; - break; - case LIBINPUT_POINTER_AXIS_SOURCE_CONTINUOUS: - wlr_event.source = WL_POINTER_AXIS_SOURCE_CONTINUOUS; - break; - case LIBINPUT_POINTER_AXIS_SOURCE_WHEEL_TILT: - wlr_event.source = WL_POINTER_AXIS_SOURCE_WHEEL_TILT; - break; + if (!axis_source_from_libinput(libinput_event_pointer_get_axis_source(pevent), &wlr_event.source)) { + wlr_log(WLR_DEBUG, "Unhandled libinput pointer axis source"); + return; } const enum libinput_pointer_axis axes[] = { LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wlroots-0.19.2/backend/libinput/switch.c new/wlroots-0.19.3/backend/libinput/switch.c --- old/wlroots-0.19.2/backend/libinput/switch.c 2025-10-22 00:21:53.000000000 +0200 +++ new/wlroots-0.19.3/backend/libinput/switch.c 2026-03-19 20:13:09.000000000 +0100 @@ -1,7 +1,9 @@ #include <assert.h> #include <libinput.h> #include <wlr/interfaces/wlr_switch.h> +#include <wlr/util/log.h> #include "backend/libinput.h" +#include "config.h" const struct wlr_switch_impl libinput_switch_impl = { .name = "libinput-switch", @@ -22,28 +24,49 @@ return dev; } +static bool switch_type_from_libinput(enum libinput_switch type, enum wlr_switch_type *out) { + switch (type) { + case LIBINPUT_SWITCH_LID: + *out = WLR_SWITCH_TYPE_LID; + return true; + case LIBINPUT_SWITCH_TABLET_MODE: + *out = WLR_SWITCH_TYPE_TABLET_MODE; + return true; +#if HAVE_LIBINPUT_SWITCH_KEYPAD_SLIDE + case LIBINPUT_SWITCH_KEYPAD_SLIDE: + *out = WLR_SWITCH_TYPE_KEYPAD_SLIDE; + return true; +#endif + } + return false; +} + +static bool switch_state_from_libinput(enum libinput_switch_state state, enum wlr_switch_state *out) { + switch (state) { + case LIBINPUT_SWITCH_STATE_OFF: + *out = WLR_SWITCH_STATE_OFF; + return true; + case LIBINPUT_SWITCH_STATE_ON: + *out = WLR_SWITCH_STATE_ON; + return true; + } + return false; +} + void handle_switch_toggle(struct libinput_event *event, struct wlr_switch *wlr_switch) { struct libinput_event_switch *sevent = - libinput_event_get_switch_event (event); + libinput_event_get_switch_event(event); struct wlr_switch_toggle_event wlr_event = { .time_msec = usec_to_msec(libinput_event_switch_get_time_usec(sevent)), }; - switch (libinput_event_switch_get_switch(sevent)) { - case LIBINPUT_SWITCH_LID: - wlr_event.switch_type = WLR_SWITCH_TYPE_LID; - break; - case LIBINPUT_SWITCH_TABLET_MODE: - wlr_event.switch_type = WLR_SWITCH_TYPE_TABLET_MODE; - break; + if (!switch_type_from_libinput(libinput_event_switch_get_switch(sevent), &wlr_event.switch_type)) { + wlr_log(WLR_DEBUG, "Unhandled libinput switch type"); + return; } - switch (libinput_event_switch_get_switch_state(sevent)) { - case LIBINPUT_SWITCH_STATE_OFF: - wlr_event.switch_state = WLR_SWITCH_STATE_OFF; - break; - case LIBINPUT_SWITCH_STATE_ON: - wlr_event.switch_state = WLR_SWITCH_STATE_ON; - break; + if (!switch_state_from_libinput(libinput_event_switch_get_switch_state(sevent), &wlr_event.switch_state)) { + wlr_log(WLR_DEBUG, "Unhandled libinput switch state"); + return; } wl_signal_emit_mutable(&wlr_switch->events.toggle, &wlr_event); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wlroots-0.19.2/backend/libinput/tablet_pad.c new/wlroots-0.19.3/backend/libinput/tablet_pad.c --- old/wlroots-0.19.2/backend/libinput/tablet_pad.c 2025-10-22 00:21:53.000000000 +0200 +++ new/wlroots-0.19.3/backend/libinput/tablet_pad.c 2026-03-19 20:13:09.000000000 +0100 @@ -148,13 +148,9 @@ .group = libinput_tablet_pad_mode_group_get_index( libinput_event_tablet_pad_get_mode_group(pevent)), }; - switch (libinput_event_tablet_pad_get_button_state(pevent)) { - case LIBINPUT_BUTTON_STATE_PRESSED: - wlr_event.state = WLR_BUTTON_PRESSED; - break; - case LIBINPUT_BUTTON_STATE_RELEASED: - wlr_event.state = WLR_BUTTON_RELEASED; - break; + if (!button_state_from_libinput(libinput_event_tablet_pad_get_button_state(pevent), &wlr_event.state)) { + wlr_log(WLR_DEBUG, "Unhandled libinput button state"); + return; } wl_signal_emit_mutable(&tablet_pad->events.button, &wlr_event); } @@ -168,6 +164,7 @@ .ring = libinput_event_tablet_pad_get_ring_number(pevent), .position = libinput_event_tablet_pad_get_ring_position(pevent), .mode = libinput_event_tablet_pad_get_mode(pevent), + .source = WLR_TABLET_PAD_RING_SOURCE_UNKNOWN, }; switch (libinput_event_tablet_pad_get_ring_source(pevent)) { case LIBINPUT_TABLET_PAD_RING_SOURCE_UNKNOWN: @@ -189,6 +186,7 @@ .strip = libinput_event_tablet_pad_get_strip_number(pevent), .position = libinput_event_tablet_pad_get_strip_position(pevent), .mode = libinput_event_tablet_pad_get_mode(pevent), + .source = WLR_TABLET_PAD_STRIP_SOURCE_UNKNOWN, }; switch (libinput_event_tablet_pad_get_strip_source(pevent)) { case LIBINPUT_TABLET_PAD_STRIP_SOURCE_UNKNOWN: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wlroots-0.19.2/backend/libinput/tablet_tool.c new/wlroots-0.19.3/backend/libinput/tablet_tool.c --- old/wlroots-0.19.2/backend/libinput/tablet_tool.c 2025-10-22 00:21:53.000000000 +0200 +++ new/wlroots-0.19.3/backend/libinput/tablet_tool.c 2026-03-19 20:13:09.000000000 +0100 @@ -68,27 +68,61 @@ return dev; } -static enum wlr_tablet_tool_type wlr_type_from_libinput_type( - enum libinput_tablet_tool_type value) { - switch (value) { +static bool type_from_libinput(enum libinput_tablet_tool_type type, + enum wlr_tablet_tool_type *out) { + switch (type) { case LIBINPUT_TABLET_TOOL_TYPE_PEN: - return WLR_TABLET_TOOL_TYPE_PEN; + *out = WLR_TABLET_TOOL_TYPE_PEN; + return true; case LIBINPUT_TABLET_TOOL_TYPE_ERASER: - return WLR_TABLET_TOOL_TYPE_ERASER; + *out = WLR_TABLET_TOOL_TYPE_ERASER; + return true; case LIBINPUT_TABLET_TOOL_TYPE_BRUSH: - return WLR_TABLET_TOOL_TYPE_BRUSH; + *out = WLR_TABLET_TOOL_TYPE_BRUSH; + return true; case LIBINPUT_TABLET_TOOL_TYPE_PENCIL: - return WLR_TABLET_TOOL_TYPE_PENCIL; + *out = WLR_TABLET_TOOL_TYPE_PENCIL; + return true; case LIBINPUT_TABLET_TOOL_TYPE_AIRBRUSH: - return WLR_TABLET_TOOL_TYPE_AIRBRUSH; + *out = WLR_TABLET_TOOL_TYPE_AIRBRUSH; + return true; case LIBINPUT_TABLET_TOOL_TYPE_MOUSE: - return WLR_TABLET_TOOL_TYPE_MOUSE; + *out = WLR_TABLET_TOOL_TYPE_MOUSE; + return true; case LIBINPUT_TABLET_TOOL_TYPE_LENS: - return WLR_TABLET_TOOL_TYPE_LENS; + *out = WLR_TABLET_TOOL_TYPE_LENS; + return true; case LIBINPUT_TABLET_TOOL_TYPE_TOTEM: - return WLR_TABLET_TOOL_TYPE_TOTEM; + *out = WLR_TABLET_TOOL_TYPE_TOTEM; + return true; } - abort(); // unreachable + return false; +} + +static bool proximity_state_from_libinput(enum libinput_tablet_tool_proximity_state state, + enum wlr_tablet_tool_proximity_state *out) { + switch (state) { + case LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_OUT: + *out = WLR_TABLET_TOOL_PROXIMITY_OUT; + return true; + case LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_IN: + *out = WLR_TABLET_TOOL_PROXIMITY_IN; + return true; + } + return false; +} + +static bool tip_state_from_libinput(enum libinput_tablet_tool_tip_state state, + enum wlr_tablet_tool_tip_state *out) { + switch (state) { + case LIBINPUT_TABLET_TOOL_TIP_UP: + *out = WLR_TABLET_TOOL_TIP_UP; + return true; + case LIBINPUT_TABLET_TOOL_TIP_DOWN: + *out = WLR_TABLET_TOOL_TIP_DOWN; + return true; + } + return false; } static struct tablet_tool *get_tablet_tool( @@ -100,14 +134,19 @@ return tool; } + enum wlr_tablet_tool_type type; + if (!type_from_libinput(libinput_tablet_tool_get_type(libinput_tool), &type)) { + wlr_log(WLR_DEBUG, "Unhandled libinput tablet tool type"); + return NULL; + } + tool = calloc(1, sizeof(*tool)); if (tool == NULL) { wlr_log_errno(WLR_ERROR, "failed to allocate wlr_libinput_tablet_tool"); return NULL; } - tool->wlr_tool.type = wlr_type_from_libinput_type( - libinput_tablet_tool_get_type(libinput_tool)); + tool->wlr_tool.type = type; tool->wlr_tool.hardware_serial = libinput_tablet_tool_get_serial(libinput_tool); tool->wlr_tool.hardware_wacom = @@ -199,14 +238,12 @@ .y = libinput_event_tablet_tool_get_y_transformed(tevent, 1), }; - switch (libinput_event_tablet_tool_get_proximity_state(tevent)) { - case LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_OUT: - wlr_event.state = WLR_TABLET_TOOL_PROXIMITY_OUT; - break; - case LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_IN: - wlr_event.state = WLR_TABLET_TOOL_PROXIMITY_IN; - break; + if (!proximity_state_from_libinput(libinput_event_tablet_tool_get_proximity_state(tevent), + &wlr_event.state)) { + wlr_log(WLR_DEBUG, "Unhandled libinput tablet tool proximity state"); + return; } + wl_signal_emit_mutable(&wlr_tablet->events.proximity, &wlr_event); if (libinput_event_tablet_tool_get_proximity_state(tevent) == @@ -241,14 +278,11 @@ .y = libinput_event_tablet_tool_get_y_transformed(tevent, 1), }; - switch (libinput_event_tablet_tool_get_tip_state(tevent)) { - case LIBINPUT_TABLET_TOOL_TIP_UP: - wlr_event.state = WLR_TABLET_TOOL_TIP_UP; - break; - case LIBINPUT_TABLET_TOOL_TIP_DOWN: - wlr_event.state = WLR_TABLET_TOOL_TIP_DOWN; - break; + if (!tip_state_from_libinput(libinput_event_tablet_tool_get_tip_state(tevent), &wlr_event.state)) { + wlr_log(WLR_DEBUG, "Unhandled libinput tablet tool tip state"); + return; } + wl_signal_emit_mutable(&wlr_tablet->events.tip, &wlr_event); } @@ -267,13 +301,11 @@ .time_msec = usec_to_msec(libinput_event_tablet_tool_get_time_usec(tevent)), .button = libinput_event_tablet_tool_get_button(tevent), }; - switch (libinput_event_tablet_tool_get_button_state(tevent)) { - case LIBINPUT_BUTTON_STATE_RELEASED: - wlr_event.state = WLR_BUTTON_RELEASED; - break; - case LIBINPUT_BUTTON_STATE_PRESSED: - wlr_event.state = WLR_BUTTON_PRESSED; - break; + + if (!button_state_from_libinput(libinput_event_tablet_tool_get_button_state(tevent), &wlr_event.state)) { + wlr_log(WLR_DEBUG, "Unhandled libinput button state"); + return; } + wl_signal_emit_mutable(&wlr_tablet->events.button, &wlr_event); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wlroots-0.19.2/backend/session/session.c new/wlroots-0.19.3/backend/session/session.c --- old/wlroots-0.19.2/backend/session/session.c 2025-10-22 00:21:53.000000000 +0200 +++ new/wlroots-0.19.3/backend/session/session.c 2026-03-19 20:13:09.000000000 +0100 @@ -36,6 +36,15 @@ static int libseat_event(int fd, uint32_t mask, void *data) { struct wlr_session *session = data; + if (mask & (WL_EVENT_HANGUP | WL_EVENT_ERROR)) { + if (mask & WL_EVENT_ERROR) { + wlr_log(WLR_ERROR, "Failed to wait for libseat event"); + } else { + wlr_log(WLR_INFO, "Failed to wait for libseat event"); + } + wlr_session_destroy(session); + return 0; + } if (libseat_dispatch(session->seat_handle, 0) == -1) { wlr_log_errno(WLR_ERROR, "Failed to dispatch libseat"); wlr_session_destroy(session); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wlroots-0.19.2/include/backend/libinput.h new/wlroots-0.19.3/include/backend/libinput.h --- old/wlroots-0.19.2/include/backend/libinput.h 2025-10-22 00:21:53.000000000 +0200 +++ new/wlroots-0.19.3/include/backend/libinput.h 2026-03-19 20:13:09.000000000 +0100 @@ -132,4 +132,6 @@ void handle_tablet_pad_strip(struct libinput_event *event, struct wlr_tablet_pad *tablet_pad); +bool button_state_from_libinput(enum libinput_button_state state, enum wlr_button_state *out); + #endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wlroots-0.19.2/include/render/vulkan.h new/wlroots-0.19.3/include/render/vulkan.h --- old/wlroots-0.19.2/include/render/vulkan.h 2025-10-22 00:21:53.000000000 +0200 +++ new/wlroots-0.19.3/include/render/vulkan.h 2026-03-19 20:13:09.000000000 +0100 @@ -433,10 +433,11 @@ bool vulkan_wait_command_buffer(struct wlr_vk_command_buffer *cb, struct wlr_vk_renderer *renderer); -bool vulkan_sync_render_buffer(struct wlr_vk_renderer *renderer, - struct wlr_vk_render_buffer *render_buffer, struct wlr_vk_command_buffer *cb, - struct wlr_drm_syncobj_timeline *signal_timeline, uint64_t signal_point); -bool vulkan_sync_foreign_texture(struct wlr_vk_texture *texture, +bool vulkan_sync_render_pass_release(struct wlr_vk_renderer *renderer, + struct wlr_vk_render_pass *pass); +bool vulkan_sync_foreign_texture_acquire(struct wlr_vk_texture *texture, + int sync_file_fds[static WLR_DMABUF_MAX_PLANES]); +bool vulkan_sync_render_buffer_acquire(struct wlr_vk_render_buffer *render_buffer, int sync_file_fds[static WLR_DMABUF_MAX_PLANES]); bool vulkan_read_pixels(struct wlr_vk_renderer *vk_renderer, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wlroots-0.19.2/include/wlr/types/wlr_switch.h new/wlroots-0.19.3/include/wlr/types/wlr_switch.h --- old/wlroots-0.19.2/include/wlr/types/wlr_switch.h 2025-10-22 00:21:53.000000000 +0200 +++ new/wlroots-0.19.3/include/wlr/types/wlr_switch.h 2026-03-19 20:13:09.000000000 +0100 @@ -36,6 +36,7 @@ enum wlr_switch_type { WLR_SWITCH_TYPE_LID, WLR_SWITCH_TYPE_TABLET_MODE, + WLR_SWITCH_TYPE_KEYPAD_SLIDE, }; enum wlr_switch_state { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wlroots-0.19.2/meson.build new/wlroots-0.19.3/meson.build --- old/wlroots-0.19.2/meson.build 2025-10-22 00:21:53.000000000 +0200 +++ new/wlroots-0.19.3/meson.build 2026-03-19 20:13:09.000000000 +0100 @@ -1,7 +1,7 @@ project( 'wlroots', 'c', - version: '0.19.2', + version: '0.19.3', license: 'MIT', meson_version: '>=1.3', default_options: [ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wlroots-0.19.2/render/allocator/shm.c new/wlroots-0.19.3/render/allocator/shm.c --- old/wlroots-0.19.2/render/allocator/shm.c 2025-10-22 00:21:53.000000000 +0200 +++ new/wlroots-0.19.3/render/allocator/shm.c 2026-03-19 20:13:09.000000000 +0100 @@ -23,6 +23,7 @@ static void buffer_destroy(struct wlr_buffer *wlr_buffer) { struct wlr_shm_buffer *buffer = shm_buffer_from_buffer(wlr_buffer); + wlr_buffer_finish(wlr_buffer); munmap(buffer->data, buffer->size); close(buffer->shm.fd); free(buffer); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wlroots-0.19.2/render/allocator/udmabuf.c new/wlroots-0.19.3/render/allocator/udmabuf.c --- old/wlroots-0.19.2/render/allocator/udmabuf.c 2025-10-22 00:21:53.000000000 +0200 +++ new/wlroots-0.19.3/render/allocator/udmabuf.c 2026-03-19 20:13:09.000000000 +0100 @@ -31,6 +31,7 @@ static void buffer_destroy(struct wlr_buffer *wlr_buffer) { struct wlr_udmabuf_buffer *buffer = wl_container_of(wlr_buffer, buffer, base); + wlr_buffer_finish(wlr_buffer); wlr_dmabuf_attributes_finish(&buffer->dmabuf); close(buffer->shm.fd); free(buffer); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wlroots-0.19.2/render/vulkan/pass.c new/wlroots-0.19.3/render/vulkan/pass.c --- old/wlroots-0.19.2/render/vulkan/pass.c 2025-10-22 00:21:53.000000000 +0200 +++ new/wlroots-0.19.3/render/vulkan/pass.c 2026-03-19 20:13:09.000000000 +0100 @@ -141,6 +141,40 @@ return *sem_ptr; } +static bool render_pass_wait_render_buffer(struct wlr_vk_render_pass *pass, + VkSemaphoreSubmitInfoKHR *render_wait, uint32_t *render_wait_len_ptr) { + int sync_file_fds[WLR_DMABUF_MAX_PLANES]; + for (size_t i = 0; i < WLR_DMABUF_MAX_PLANES; i++) { + sync_file_fds[i] = -1; + } + + if (!vulkan_sync_render_buffer_acquire(pass->render_buffer, sync_file_fds)) { + return false; + } + + for (size_t i = 0; i < WLR_DMABUF_MAX_PLANES; i++) { + if (sync_file_fds[i] < 0) { + continue; + } + + VkSemaphore sem = render_pass_wait_sync_file(pass, *render_wait_len_ptr, sync_file_fds[i]); + if (sem == VK_NULL_HANDLE) { + close(sync_file_fds[i]); + continue; + } + + render_wait[*render_wait_len_ptr] = (VkSemaphoreSubmitInfoKHR){ + .sType = VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO_KHR, + .semaphore = sem, + .stageMask = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT_KHR, + }; + + (*render_wait_len_ptr)++; + } + + return true; +} + static bool render_pass_submit(struct wlr_render_pass *wlr_pass) { struct wlr_vk_render_pass *pass = get_render_pass(wlr_pass); struct wlr_vk_renderer *renderer = pass->renderer; @@ -236,7 +270,7 @@ vkCmdEndRenderPass(render_cb->vk); size_t pass_textures_len = pass->textures.size / sizeof(struct wlr_vk_render_pass_texture); - size_t render_wait_cap = pass_textures_len * WLR_DMABUF_MAX_PLANES; + size_t render_wait_cap = (1 + pass_textures_len) * WLR_DMABUF_MAX_PLANES; render_wait = calloc(render_wait_cap, sizeof(*render_wait)); if (render_wait == NULL) { wlr_log_errno(WLR_ERROR, "Allocation failed"); @@ -314,7 +348,7 @@ sync_file_fds[0] = sync_file_fd; } else { struct wlr_vk_texture *texture = pass_texture->texture; - if (!vulkan_sync_foreign_texture(texture, sync_file_fds)) { + if (!vulkan_sync_foreign_texture_acquire(texture, sync_file_fds)) { wlr_log(WLR_ERROR, "Failed to wait for foreign texture DMA-BUF fence"); continue; } @@ -341,6 +375,10 @@ } } + if (!render_pass_wait_render_buffer(pass, render_wait, &render_wait_len)) { + wlr_log(WLR_ERROR, "Failed to wait for render buffer DMA-BUF fence"); + } + // also add acquire/release barriers for the current render buffer VkImageLayout src_layout = VK_IMAGE_LAYOUT_GENERAL; if (pass->srgb_pathway) { @@ -538,8 +576,7 @@ wl_list_insert(&stage_cb->stage_buffers, &stage_buf->link); } - if (!vulkan_sync_render_buffer(renderer, render_buffer, render_cb, - pass->signal_timeline, pass->signal_point)) { + if (!vulkan_sync_render_pass_release(renderer, pass)) { wlr_log(WLR_ERROR, "Failed to sync render buffer"); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wlroots-0.19.2/render/vulkan/renderer.c new/wlroots-0.19.3/render/vulkan/renderer.c --- old/wlroots-0.19.2/render/vulkan/renderer.c 2025-10-22 00:21:53.000000000 +0200 +++ new/wlroots-0.19.3/render/vulkan/renderer.c 2026-03-19 20:13:09.000000000 +0100 @@ -947,13 +947,11 @@ return buffer; } -bool vulkan_sync_foreign_texture(struct wlr_vk_texture *texture, - int sync_file_fds[static WLR_DMABUF_MAX_PLANES]) { - struct wlr_vk_renderer *renderer = texture->renderer; - +static bool buffer_export_sync_file(struct wlr_vk_renderer *renderer, struct wlr_buffer *buffer, + uint32_t flags, int sync_file_fds[static WLR_DMABUF_MAX_PLANES]) { struct wlr_dmabuf_attributes dmabuf = {0}; - if (!wlr_buffer_get_dmabuf(texture->buffer, &dmabuf)) { - wlr_log(WLR_ERROR, "Failed to get texture DMA-BUF"); + if (!wlr_buffer_get_dmabuf(buffer, &dmabuf)) { + wlr_log(WLR_ERROR, "wlr_buffer_get_dmabuf() failed"); return false; } @@ -963,7 +961,7 @@ for (int i = 0; i < dmabuf.n_planes; i++) { struct pollfd pollfd = { .fd = dmabuf.fd[i], - .events = POLLIN, + .events = (flags & DMA_BUF_SYNC_WRITE) ? POLLOUT : POLLIN, }; int timeout_ms = 1000; int ret = poll(&pollfd, 1, timeout_ms); @@ -980,7 +978,7 @@ } for (int i = 0; i < dmabuf.n_planes; i++) { - int sync_file_fd = dmabuf_export_sync_file(dmabuf.fd[i], DMA_BUF_SYNC_READ); + int sync_file_fd = dmabuf_export_sync_file(dmabuf.fd[i], flags); if (sync_file_fd < 0) { wlr_log(WLR_ERROR, "Failed to extract DMA-BUF fence"); return false; @@ -992,12 +990,40 @@ return true; } -bool vulkan_sync_render_buffer(struct wlr_vk_renderer *renderer, - struct wlr_vk_render_buffer *render_buffer, struct wlr_vk_command_buffer *cb, - struct wlr_drm_syncobj_timeline *signal_timeline, uint64_t signal_point) { +bool vulkan_sync_foreign_texture_acquire(struct wlr_vk_texture *texture, + int sync_file_fds[static WLR_DMABUF_MAX_PLANES]) { + return buffer_export_sync_file(texture->renderer, texture->buffer, DMA_BUF_SYNC_READ, sync_file_fds); +} + +bool vulkan_sync_render_buffer_acquire(struct wlr_vk_render_buffer *render_buffer, + int sync_file_fds[static WLR_DMABUF_MAX_PLANES]) { + return buffer_export_sync_file(render_buffer->renderer, render_buffer->wlr_buffer, + DMA_BUF_SYNC_WRITE, sync_file_fds); +} + +static bool buffer_import_sync_file(struct wlr_buffer *buffer, uint32_t flags, int sync_file_fd) { + struct wlr_dmabuf_attributes dmabuf = {0}; + if (!wlr_buffer_get_dmabuf(buffer, &dmabuf)) { + wlr_log(WLR_ERROR, "wlr_buffer_get_dmabuf() failed"); + return false; + } + + for (int i = 0; i < dmabuf.n_planes; i++) { + if (!dmabuf_import_sync_file(dmabuf.fd[i], flags, + sync_file_fd)) { + return false; + } + } + + return true; +} + +bool vulkan_sync_render_pass_release(struct wlr_vk_renderer *renderer, + struct wlr_vk_render_pass *pass) { VkResult res; + struct wlr_vk_command_buffer *cb = pass->command_buffer; - if (!renderer->dev->implicit_sync_interop && signal_timeline == NULL) { + if (!renderer->dev->implicit_sync_interop && pass->signal_timeline == NULL) { // We have no choice but to block here sadly return vulkan_wait_command_buffer(cb, renderer); } @@ -1019,21 +1045,19 @@ } bool ok = false; - if (signal_timeline != NULL) { - if (!wlr_drm_syncobj_timeline_import_sync_file(signal_timeline, - signal_point, sync_file_fd)) { + if (pass->signal_timeline != NULL) { + if (!wlr_drm_syncobj_timeline_import_sync_file(pass->signal_timeline, + pass->signal_point, sync_file_fd)) { goto out; } } else { - struct wlr_dmabuf_attributes dmabuf = {0}; - if (!wlr_buffer_get_dmabuf(render_buffer->wlr_buffer, &dmabuf)) { - wlr_log(WLR_ERROR, "wlr_buffer_get_dmabuf failed"); + if (!buffer_import_sync_file(pass->render_buffer->wlr_buffer, DMA_BUF_SYNC_WRITE, sync_file_fd)) { goto out; } - for (int i = 0; i < dmabuf.n_planes; i++) { - if (!dmabuf_import_sync_file(dmabuf.fd[i], DMA_BUF_SYNC_WRITE, - sync_file_fd)) { + struct wlr_vk_render_pass_texture *pass_texture; + wl_array_for_each(pass_texture, &pass->textures) { + if (!buffer_import_sync_file(pass_texture->texture->buffer, DMA_BUF_SYNC_READ, sync_file_fd)) { goto out; } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wlroots-0.19.2/tinywl/Makefile new/wlroots-0.19.3/tinywl/Makefile --- old/wlroots-0.19.2/tinywl/Makefile 2025-10-22 00:21:53.000000000 +0200 +++ new/wlroots-0.19.3/tinywl/Makefile 2026-03-19 20:13:09.000000000 +0100 @@ -19,7 +19,7 @@ tinywl.o: tinywl.c xdg-shell-protocol.h $(CC) -c $< -g -Werror $(CFLAGS) -I. -DWLR_USE_UNSTABLE -o $@ tinywl: tinywl.o - $(CC) $^ $> -g -Werror $(CFLAGS) $(LDFLAGS) $(LIBS) -o $@ + $(CC) $^ -g -Werror $(CFLAGS) $(LDFLAGS) $(LIBS) -o $@ clean: rm -f tinywl tinywl.o xdg-shell-protocol.h diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wlroots-0.19.2/types/ext_image_capture_source_v1/output.c new/wlroots-0.19.3/types/ext_image_capture_source_v1/output.c --- old/wlroots-0.19.2/types/ext_image_capture_source_v1/output.c 2025-10-22 00:21:53.000000000 +0200 +++ new/wlroots-0.19.3/types/ext_image_capture_source_v1/output.c 2026-03-19 20:13:09.000000000 +0100 @@ -107,6 +107,10 @@ static void source_update_buffer_constraints(struct wlr_ext_output_image_capture_source_v1 *source) { struct wlr_output *output = source->output; + if (!output->enabled) { + return; + } + if (!wlr_output_configure_primary_swapchain(output, NULL, &output->swapchain)) { return; } @@ -120,7 +124,8 @@ struct wlr_ext_output_image_capture_source_v1 *source = wl_container_of(listener, source, output_commit); struct wlr_output_event_commit *event = data; - if (event->state->committed & (WLR_OUTPUT_STATE_MODE | WLR_OUTPUT_STATE_RENDER_FORMAT)) { + if (event->state->committed & (WLR_OUTPUT_STATE_MODE | + WLR_OUTPUT_STATE_RENDER_FORMAT | WLR_OUTPUT_STATE_ENABLED)) { source_update_buffer_constraints(source); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wlroots-0.19.2/types/wlr_virtual_pointer_v1.c new/wlroots-0.19.3/types/wlr_virtual_pointer_v1.c --- old/wlroots-0.19.2/types/wlr_virtual_pointer_v1.c 2025-10-22 00:21:53.000000000 +0200 +++ new/wlroots-0.19.3/types/wlr_virtual_pointer_v1.c 2026-03-19 20:13:09.000000000 +0100 @@ -134,8 +134,11 @@ if (pointer == NULL) { return; } - pointer->axis_event[pointer->axis].pointer = &pointer->pointer; - pointer->axis_event[pointer->axis].source = source; + int n_axis = sizeof(pointer->axis_event) / sizeof(pointer->axis_event[0]); + for (int i = 0; i < n_axis; i++) { + pointer->axis_event[i].pointer = &pointer->pointer; + pointer->axis_event[i].source = source; + } } static void virtual_pointer_axis_stop(struct wl_client *client, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wlroots-0.19.2/xcursor/xcursor.c new/wlroots-0.19.3/xcursor/xcursor.c --- old/wlroots-0.19.2/xcursor/xcursor.c 2025-10-22 00:21:53.000000000 +0200 +++ new/wlroots-0.19.3/xcursor/xcursor.c 2026-03-19 20:13:09.000000000 +0100 @@ -602,7 +602,7 @@ static const char * xcursor_next_path(const char *path) { - char *colon = strchr(path, ':'); + const char *colon = strchr(path, ':'); if (!colon) return NULL; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wlroots-0.19.2/xwayland/selection/outgoing.c new/wlroots-0.19.3/xwayland/selection/outgoing.c --- old/wlroots-0.19.2/xwayland/selection/outgoing.c 2025-10-22 00:21:53.000000000 +0200 +++ new/wlroots-0.19.3/xwayland/selection/outgoing.c 2026-03-19 20:13:09.000000000 +0100 @@ -283,6 +283,8 @@ int p[2]; if (pipe(p) == -1) { wlr_log_errno(WLR_ERROR, "pipe() failed"); + wl_array_release(&transfer->source_data); + free(transfer); return false; }
