mirror of
https://github.com/hyprwm/wlroots-hyprland.git
synced 2024-11-25 22:25:58 +01:00
backend: destroy multi backend when primary backend is
This makes it easy for compositors to handle situations where the DRM or libinput backend becomes unavailable. Compositors can listen the destroy event of the multi backend returned by wlr_backend_autocreate() and decide what to do.
This commit is contained in:
parent
be0b7845f7
commit
4ad6e6c298
2 changed files with 67 additions and 2 deletions
|
@ -146,6 +146,53 @@ static size_t parse_outputs_env(const char *name) {
|
||||||
return outputs;
|
return outputs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper to destroy the multi backend when one of its nested backends is
|
||||||
|
* destroyed.
|
||||||
|
*/
|
||||||
|
struct wlr_auto_backend_monitor {
|
||||||
|
struct wlr_backend *multi;
|
||||||
|
struct wlr_backend *primary;
|
||||||
|
|
||||||
|
struct wl_listener multi_destroy;
|
||||||
|
struct wl_listener primary_destroy;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void auto_backend_monitor_destroy(struct wlr_auto_backend_monitor *monitor) {
|
||||||
|
wl_list_remove(&monitor->multi_destroy.link);
|
||||||
|
wl_list_remove(&monitor->primary_destroy.link);
|
||||||
|
free(monitor);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void monitor_handle_multi_destroy(struct wl_listener *listener, void *data) {
|
||||||
|
struct wlr_auto_backend_monitor *monitor = wl_container_of(listener, monitor, multi_destroy);
|
||||||
|
auto_backend_monitor_destroy(monitor);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void monitor_handle_primary_destroy(struct wl_listener *listener, void *data) {
|
||||||
|
struct wlr_auto_backend_monitor *monitor = wl_container_of(listener, monitor, primary_destroy);
|
||||||
|
wlr_backend_destroy(monitor->multi);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct wlr_auto_backend_monitor *auto_backend_monitor_create(
|
||||||
|
struct wlr_backend *multi, struct wlr_backend *primary) {
|
||||||
|
struct wlr_auto_backend_monitor *monitor = calloc(1, sizeof(*monitor));
|
||||||
|
if (monitor == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
monitor->multi = multi;
|
||||||
|
monitor->primary = primary;
|
||||||
|
|
||||||
|
monitor->multi_destroy.notify = monitor_handle_multi_destroy;
|
||||||
|
wl_signal_add(&multi->events.destroy, &monitor->multi_destroy);
|
||||||
|
|
||||||
|
monitor->primary_destroy.notify = monitor_handle_primary_destroy;
|
||||||
|
wl_signal_add(&primary->events.destroy, &monitor->primary_destroy);
|
||||||
|
|
||||||
|
return monitor;
|
||||||
|
}
|
||||||
|
|
||||||
static struct wlr_backend *attempt_wl_backend(struct wl_display *display) {
|
static struct wlr_backend *attempt_wl_backend(struct wl_display *display) {
|
||||||
struct wlr_backend *backend = wlr_wl_backend_create(display, NULL);
|
struct wlr_backend *backend = wlr_wl_backend_create(display, NULL);
|
||||||
if (backend == NULL) {
|
if (backend == NULL) {
|
||||||
|
@ -335,8 +382,12 @@ struct wlr_backend *wlr_backend_autocreate(struct wl_display *display,
|
||||||
if (!wl_backend) {
|
if (!wl_backend) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
wlr_multi_backend_add(multi, wl_backend);
|
wlr_multi_backend_add(multi, wl_backend);
|
||||||
|
|
||||||
|
if (!auto_backend_monitor_create(multi, wl_backend)) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
goto success;
|
goto success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -347,8 +398,12 @@ struct wlr_backend *wlr_backend_autocreate(struct wl_display *display,
|
||||||
if (!x11_backend) {
|
if (!x11_backend) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
wlr_multi_backend_add(multi, x11_backend);
|
wlr_multi_backend_add(multi, x11_backend);
|
||||||
|
|
||||||
|
if (!auto_backend_monitor_create(multi, x11_backend)) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
goto success;
|
goto success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -362,6 +417,9 @@ struct wlr_backend *wlr_backend_autocreate(struct wl_display *display,
|
||||||
struct wlr_backend *libinput = attempt_libinput_backend(display, session);
|
struct wlr_backend *libinput = attempt_libinput_backend(display, session);
|
||||||
if (libinput) {
|
if (libinput) {
|
||||||
wlr_multi_backend_add(multi, libinput);
|
wlr_multi_backend_add(multi, libinput);
|
||||||
|
if (!auto_backend_monitor_create(multi, libinput)) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
} else if (env_parse_bool("WLR_LIBINPUT_NO_DEVICES")) {
|
} else if (env_parse_bool("WLR_LIBINPUT_NO_DEVICES")) {
|
||||||
wlr_log(WLR_INFO, "WLR_LIBINPUT_NO_DEVICES is set, "
|
wlr_log(WLR_INFO, "WLR_LIBINPUT_NO_DEVICES is set, "
|
||||||
"starting without libinput backend");
|
"starting without libinput backend");
|
||||||
|
@ -377,6 +435,10 @@ struct wlr_backend *wlr_backend_autocreate(struct wl_display *display,
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!auto_backend_monitor_create(multi, primary_drm)) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
success:
|
success:
|
||||||
if (session_ptr != NULL) {
|
if (session_ptr != NULL) {
|
||||||
*session_ptr = session;
|
*session_ptr = session;
|
||||||
|
|
|
@ -37,6 +37,9 @@ struct wlr_backend {
|
||||||
*
|
*
|
||||||
* If session_ptr is not NULL, it's populated with the session which has been
|
* If session_ptr is not NULL, it's populated with the session which has been
|
||||||
* created with the backend, if any.
|
* created with the backend, if any.
|
||||||
|
*
|
||||||
|
* The multi-backend will be destroyed if one of the primary underlying
|
||||||
|
* backends is destroyed (e.g. if the primary DRM device is unplugged).
|
||||||
*/
|
*/
|
||||||
struct wlr_backend *wlr_backend_autocreate(struct wl_display *display,
|
struct wlr_backend *wlr_backend_autocreate(struct wl_display *display,
|
||||||
struct wlr_session **session_ptr);
|
struct wlr_session **session_ptr);
|
||||||
|
|
Loading…
Reference in a new issue