Download raw body.
Testing: wayland monitor hotplug
During l2k25 I tried to get output hotplug to work with wlroots based wayland
compositors. The attached diff seems to work rather well for matthieu@ and myself
but could probably use some wider testing from whoever is interested :-)
For those who haven't used wayland on OpenBSD before:
$ doas pkg_add sway
* apply the attached diff to wayland/wlroots, rebuild and install
* kill all running X sessions, make sure to stop xenodm if it's running
$ startsway.sh
* Plug, unplug and replug any external monitors you have around, and see if
sway detects and uses them.
Index: Makefile
===================================================================
RCS file: /cvs/ports/wayland/wlroots/Makefile,v
diff -u -p -r1.11 Makefile
--- Makefile 16 Dec 2024 18:25:23 -0000 1.11
+++ Makefile 5 Aug 2025 17:21:53 -0000
@@ -2,6 +2,7 @@ COMMENT = modular Wayland compositor lib
V = 0.18.2
EPOCH = 0
+REVISION = 0
DISTNAME = wlroots-${V}
CATEGORIES = wayland
Index: patches/patch-backend_drm_backend_c
===================================================================
RCS file: patches/patch-backend_drm_backend_c
diff -N patches/patch-backend_drm_backend_c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ patches/patch-backend_drm_backend_c 5 Aug 2025 17:21:53 -0000
@@ -0,0 +1,45 @@
+Index: backend/drm/backend.c
+--- backend/drm/backend.c.orig
++++ backend/drm/backend.c
+@@ -10,6 +10,7 @@
+ #include <wlr/backend/session.h>
+ #include <wlr/interfaces/wlr_output.h>
+ #include <wlr/util/log.h>
++#include <sys/event.h>
+ #include <xf86drm.h>
+ #include "backend/drm/drm.h"
+ #include "backend/drm/fb.h"
+@@ -167,6 +168,8 @@ static void handle_parent_destroy(struct wl_listener *
+
+ struct wlr_backend *wlr_drm_backend_create(struct wlr_session *session,
+ struct wlr_device *dev, struct wlr_backend *parent) {
++ int kq;
++ struct kevent kev;
+ assert(session && dev);
+ assert(!parent || wlr_backend_is_drm(parent));
+
+@@ -267,6 +270,24 @@ struct wlr_backend *wlr_drm_backend_create(struct wlr_
+ drm->session_destroy.notify = handle_session_destroy;
+ wl_signal_add(&session->events.destroy, &drm->session_destroy);
+
++ if ((kq = kqueue()) <= 0)
++ goto error_kqueue;
++
++ EV_SET(&kev, dev->fd, EVFILT_DEVICE, EV_ADD | EV_ENABLE | EV_CLEAR,
++ NOTE_CHANGE, 0, NULL);
++
++ if (kevent(kq, &kev, 1, NULL, 0, NULL) < 0)
++ goto error_kqueue;
++
++ drm->drm_kevent = wl_event_loop_add_fd(session->event_loop, kq,
++ WL_EVENT_READABLE, handle_drm_kevent, drm);
++ if (!drm->drm_kevent) {
++ wlr_log(WLR_ERROR, "Failed to create DRM kevent source");
++ goto error_kqueue;
++ }
++ wlr_log(WLR_INFO, "DRM kevent source added");
++
++error_kqueue:
+ return &drm->backend;
+
+ error_mgpu_renderer:
Index: patches/patch-backend_drm_drm_c
===================================================================
RCS file: patches/patch-backend_drm_drm_c
diff -N patches/patch-backend_drm_drm_c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ patches/patch-backend_drm_drm_c 5 Aug 2025 17:21:53 -0000
@@ -0,0 +1,30 @@
+Index: backend/drm/drm.c
+--- backend/drm/drm.c.orig
++++ backend/drm/drm.c
+@@ -9,6 +9,7 @@
+ #include <stdlib.h>
+ #include <string.h>
+ #include <strings.h>
++#include <sys/event.h>
+ #include <time.h>
+ #include <wayland-server-core.h>
+ #include <wayland-util.h>
+@@ -2113,6 +2114,18 @@ int handle_drm_event(int fd, uint32_t mask, void *data
+ wlr_log(WLR_ERROR, "drmHandleEvent failed");
+ wlr_backend_destroy(&drm->backend);
+ }
++ return 1;
++}
++
++int handle_drm_kevent(int fd, uint32_t mask, void *data) {
++ struct kevent kev;
++ struct wlr_drm_backend *drm = data;
++
++ if ((kevent(fd, NULL, 0, &kev, 1, NULL)) && kev.fflags & NOTE_CHANGE) {
++ wlr_log(WLR_INFO, "drm hotplug detected");
++ scan_drm_connectors(drm, NULL);
++ }
++
+ return 1;
+ }
+
Index: patches/patch-include_backend_drm_drm_h
===================================================================
RCS file: patches/patch-include_backend_drm_drm_h
diff -N patches/patch-include_backend_drm_drm_h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ patches/patch-include_backend_drm_drm_h 5 Aug 2025 17:21:53 -0000
@@ -0,0 +1,19 @@
+Index: include/backend/drm/drm.h
+--- include/backend/drm/drm.h.orig
++++ include/backend/drm/drm.h
+@@ -96,6 +96,7 @@ struct wlr_drm_backend {
+ struct wlr_drm_plane *planes;
+
+ struct wl_event_source *drm_event;
++ struct wl_event_source *drm_kevent;
+
+ struct wl_listener session_destroy;
+ struct wl_listener session_active;
+@@ -215,6 +216,7 @@ bool commit_drm_device(struct wlr_drm_backend *drm,
+ const struct wlr_backend_output_state *states, size_t states_len, bool test_only);
+ void restore_drm_device(struct wlr_drm_backend *drm);
+ int handle_drm_event(int fd, uint32_t mask, void *data);
++int handle_drm_kevent(int fd, uint32_t mask, void *data);
+ void destroy_drm_connector(struct wlr_drm_connector *conn);
+ bool drm_connector_is_cursor_visible(struct wlr_drm_connector *conn);
+ size_t drm_crtc_get_gamma_lut_size(struct wlr_drm_backend *drm,
Testing: wayland monitor hotplug