Don't ignore initialisation errors

server_init ignores all errors. In practice, theses result in a
segfault, potentially much later and losing any unsaved work.

Properly handle initialisation errors and bail immediately.

(cherry picked from commit 1606311553)
This commit is contained in:
Hugo Osvaldo Barrera 2026-04-09 02:09:59 +02:00 committed by Simon Ser
parent faedde4e77
commit 0df0173102
5 changed files with 222 additions and 23 deletions

View file

@ -176,7 +176,7 @@ void handle_new_output(struct wl_listener *listener, void *data);
void handle_idle_inhibitor_v1(struct wl_listener *listener, void *data);
void handle_layer_shell_surface(struct wl_listener *listener, void *data);
void sway_session_lock_init(void);
bool sway_session_lock_init(void);
void sway_session_lock_add_output(struct sway_session_lock *lock,
struct sway_output *output);
bool sway_session_lock_has_surface(struct sway_session_lock *lock,

View file

@ -162,7 +162,7 @@ void workspace_squash(struct sway_workspace *workspace);
void workspace_move_to_output(struct sway_workspace *workspace,
struct sway_output *output);
void sway_ext_workspace_init(void);
bool sway_ext_workspace_init(void);
void sway_ext_workspace_output_enable(struct sway_output *output);
void sway_ext_workspace_output_disable(struct sway_output *output);

View file

@ -344,8 +344,12 @@ bool sway_session_lock_has_surface(struct sway_session_lock *lock,
return false;
}
void sway_session_lock_init(void) {
bool sway_session_lock_init(void) {
server.session_lock.manager = wlr_session_lock_manager_v1_create(server.wl_display);
if (!server.session_lock.manager) {
sway_log(SWAY_ERROR, "Failed to create session lock manager");
return false;
}
server.session_lock.new_lock.notify = handle_session_lock;
server.session_lock.manager_destroy.notify = handle_session_lock_destroy;
@ -353,4 +357,5 @@ void sway_session_lock_init(void) {
&server.session_lock.new_lock);
wl_signal_add(&server.session_lock.manager->events.destroy,
&server.session_lock.manager_destroy);
return true;
}

View file

@ -244,13 +244,25 @@ static void handle_new_foreign_toplevel_capture_request(struct wl_listener *list
bool server_init(struct sway_server *server) {
sway_log(SWAY_DEBUG, "Initializing Wayland server");
server->wl_display = wl_display_create();
if (!server->wl_display) {
sway_log(SWAY_ERROR, "Failed to create wl_display");
return false;
}
server->wl_event_loop = wl_display_get_event_loop(server->wl_display);
wl_display_set_global_filter(server->wl_display, filter_global, NULL);
wl_display_set_default_max_buffer_size(server->wl_display, 1024 * 1024);
wlr_fixes_create(server->wl_display, 1);
if (!wlr_fixes_create(server->wl_display, 1)) {
sway_log(SWAY_ERROR, "Failed to create wp_fixes global");
return false;
}
root = root_create(server->wl_display);
if (!root) {
sway_log(SWAY_ERROR, "Failed to create root");
wl_display_destroy(server->wl_display);
return false;
}
server->backend = wlr_backend_autocreate(server->wl_event_loop, &server->session);
if (!server->backend) {
@ -271,15 +283,23 @@ bool server_init(struct sway_server *server) {
wlr_renderer_init_wl_shm(server->renderer, server->wl_display);
if (wlr_renderer_get_texture_formats(server->renderer, WLR_BUFFER_CAP_DMABUF) != NULL) {
if (wlr_renderer_get_drm_fd(server->renderer) >= 0 &&
wlr_renderer_get_texture_formats(server->renderer, WLR_BUFFER_CAP_DMABUF) != NULL) {
server->linux_dmabuf_v1 = wlr_linux_dmabuf_v1_create_with_renderer(
server->wl_display, 5, server->renderer);
if (!server->linux_dmabuf_v1) {
sway_log(SWAY_ERROR, "Failed to create linux-dmabuf v1");
return false;
}
}
if (wlr_renderer_get_drm_fd(server->renderer) >= 0 &&
server->renderer->features.timeline &&
server->backend->features.timeline) {
wlr_linux_drm_syncobj_manager_v1_create(server->wl_display, 1,
wlr_renderer_get_drm_fd(server->renderer));
if (!wlr_linux_drm_syncobj_manager_v1_create(server->wl_display, 1,
wlr_renderer_get_drm_fd(server->renderer))) {
sway_log(SWAY_ERROR, "Failed to create linux-drm-syncobj v1");
return false;
}
}
server->allocator = wlr_allocator_autocreate(server->backend,
@ -291,14 +311,29 @@ bool server_init(struct sway_server *server) {
server->compositor = wlr_compositor_create(server->wl_display, 6,
server->renderer);
if (!server->compositor) {
sway_log(SWAY_ERROR, "Failed to create compositor");
return false;
}
wlr_subcompositor_create(server->wl_display);
if (!wlr_subcompositor_create(server->wl_display)) {
sway_log(SWAY_ERROR, "Failed to create subcompositor");
return false;
}
server->data_device_manager =
wlr_data_device_manager_create(server->wl_display);
if (!server->data_device_manager) {
sway_log(SWAY_ERROR, "Failed to create data device manager");
return false;
}
server->gamma_control_manager_v1 =
wlr_gamma_control_manager_v1_create(server->wl_display);
if (!server->gamma_control_manager_v1) {
sway_log(SWAY_ERROR, "Failed to create gamma control manager");
return false;
}
wlr_scene_set_gamma_control_manager_v1(root->root_scene,
server->gamma_control_manager_v1);
@ -307,26 +342,53 @@ bool server_init(struct sway_server *server) {
server->xdg_output_manager_v1 =
wlr_xdg_output_manager_v1_create(server->wl_display, root->output_layout);
if (!server->xdg_output_manager_v1) {
sway_log(SWAY_ERROR, "Failed to create XDG output manager");
return false;
}
server->idle_notifier_v1 = wlr_idle_notifier_v1_create(server->wl_display);
sway_idle_inhibit_manager_v1_init();
if (!server->idle_notifier_v1) {
sway_log(SWAY_ERROR, "Failed to create idle notifier");
return false;
}
if (!sway_idle_inhibit_manager_v1_init()) {
sway_log(SWAY_ERROR, "Failed to init idle inhibit manager");
return false;
}
server->layer_shell = wlr_layer_shell_v1_create(server->wl_display,
SWAY_LAYER_SHELL_VERSION);
if (!server->layer_shell) {
sway_log(SWAY_ERROR, "Failed to create layer shell");
return false;
}
wl_signal_add(&server->layer_shell->events.new_surface,
&server->layer_shell_surface);
server->layer_shell_surface.notify = handle_layer_shell_surface;
server->xdg_shell = wlr_xdg_shell_create(server->wl_display,
SWAY_XDG_SHELL_VERSION);
if (!server->xdg_shell) {
sway_log(SWAY_ERROR, "Failed to create XDG shell");
return false;
}
wl_signal_add(&server->xdg_shell->events.new_toplevel,
&server->xdg_shell_toplevel);
server->xdg_shell_toplevel.notify = handle_xdg_shell_toplevel;
server->tablet_v2 = wlr_tablet_v2_create(server->wl_display);
if (!server->tablet_v2) {
sway_log(SWAY_ERROR, "Failed to create tablet manager");
return false;
}
server->server_decoration_manager =
wlr_server_decoration_manager_create(server->wl_display);
if (!server->server_decoration_manager) {
sway_log(SWAY_ERROR, "Failed to create server decoration manager");
return false;
}
wlr_server_decoration_manager_set_default_mode(
server->server_decoration_manager,
WLR_SERVER_DECORATION_MANAGER_MODE_SERVER);
@ -337,6 +399,10 @@ bool server_init(struct sway_server *server) {
server->xdg_decoration_manager =
wlr_xdg_decoration_manager_v1_create(server->wl_display);
if (!server->xdg_decoration_manager) {
sway_log(SWAY_ERROR, "Failed to create XDG decoration manager");
return false;
}
wl_signal_add(
&server->xdg_decoration_manager->events.new_toplevel_decoration,
&server->xdg_decoration);
@ -345,18 +411,36 @@ bool server_init(struct sway_server *server) {
server->relative_pointer_manager =
wlr_relative_pointer_manager_v1_create(server->wl_display);
if (!server->relative_pointer_manager) {
sway_log(SWAY_ERROR, "Failed to create relative pointer manager");
return false;
}
server->pointer_constraints =
wlr_pointer_constraints_v1_create(server->wl_display);
if (!server->pointer_constraints) {
sway_log(SWAY_ERROR, "Failed to create pointer constraints");
return false;
}
server->pointer_constraint.notify = handle_pointer_constraint;
wl_signal_add(&server->pointer_constraints->events.new_constraint,
&server->pointer_constraint);
wlr_presentation_create(server->wl_display, server->backend, SWAY_PRESENTATION_VERSION);
wlr_alpha_modifier_v1_create(server->wl_display);
if (!wlr_presentation_create(server->wl_display, server->backend, SWAY_PRESENTATION_VERSION)) {
sway_log(SWAY_ERROR, "Failed to create presentation");
return false;
}
if (!wlr_alpha_modifier_v1_create(server->wl_display)) {
sway_log(SWAY_ERROR, "Failed to create alpha modifier");
return false;
}
server->output_manager_v1 =
wlr_output_manager_v1_create(server->wl_display);
if (!server->output_manager_v1) {
sway_log(SWAY_ERROR, "Failed to create output manager");
return false;
}
server->output_manager_apply.notify = handle_output_manager_apply;
wl_signal_add(&server->output_manager_v1->events.apply,
&server->output_manager_apply);
@ -366,19 +450,43 @@ bool server_init(struct sway_server *server) {
server->output_power_manager_v1 =
wlr_output_power_manager_v1_create(server->wl_display);
if (!server->output_power_manager_v1) {
sway_log(SWAY_ERROR, "Failed to create output power manager");
return false;
}
server->output_power_manager_set_mode.notify =
handle_output_power_manager_set_mode;
wl_signal_add(&server->output_power_manager_v1->events.set_mode,
&server->output_power_manager_set_mode);
server->input_method = wlr_input_method_manager_v2_create(server->wl_display);
if (!server->input_method) {
sway_log(SWAY_ERROR, "Failed to create input method manager");
return false;
}
server->text_input = wlr_text_input_manager_v3_create(server->wl_display);
if (!server->text_input) {
sway_log(SWAY_ERROR, "Failed to create text input manager");
return false;
}
server->foreign_toplevel_list =
wlr_ext_foreign_toplevel_list_v1_create(server->wl_display, SWAY_FOREIGN_TOPLEVEL_LIST_VERSION);
if (!server->foreign_toplevel_list) {
sway_log(SWAY_ERROR, "Failed to create foreign toplevel list");
return false;
}
server->foreign_toplevel_manager =
wlr_foreign_toplevel_manager_v1_create(server->wl_display);
if (!server->foreign_toplevel_manager) {
sway_log(SWAY_ERROR, "Failed to create foreign toplevel manager");
return false;
}
sway_session_lock_init();
sway_ext_workspace_init();
if (!sway_session_lock_init()) {
return false;
}
if (!sway_ext_workspace_init()) {
return false;
}
#if WLR_HAS_DRM_BACKEND
server->drm_lease_manager=
@ -394,26 +502,74 @@ bool server_init(struct sway_server *server) {
#endif
server->export_dmabuf_manager_v1 = wlr_export_dmabuf_manager_v1_create(server->wl_display);
if (!server->export_dmabuf_manager_v1) {
sway_log(SWAY_ERROR, "Failed to create export dmabuf manager");
return false;
}
server->screencopy_manager_v1 = wlr_screencopy_manager_v1_create(server->wl_display);
if (!server->screencopy_manager_v1) {
sway_log(SWAY_ERROR, "Failed to create screencopy manager");
return false;
}
server->ext_image_copy_capture_manager_v1 = wlr_ext_image_copy_capture_manager_v1_create(server->wl_display, 1);
wlr_ext_output_image_capture_source_manager_v1_create(server->wl_display, 1);
if (!server->ext_image_copy_capture_manager_v1) {
sway_log(SWAY_ERROR, "Failed to create ext image copy capture manager");
return false;
}
if (!wlr_ext_output_image_capture_source_manager_v1_create(server->wl_display, 1)) {
sway_log(SWAY_ERROR, "Failed to create ext output image capture source manager");
return false;
}
server->wlr_data_control_manager_v1 = wlr_data_control_manager_v1_create(server->wl_display);
if (!server->wlr_data_control_manager_v1) {
sway_log(SWAY_ERROR, "Failed to create data control manager");
return false;
}
server->ext_data_control_manager_v1 = wlr_ext_data_control_manager_v1_create(server->wl_display, 1);
if (!server->ext_data_control_manager_v1) {
sway_log(SWAY_ERROR, "Failed to create ext data control manager");
return false;
}
server->security_context_manager_v1 = wlr_security_context_manager_v1_create(server->wl_display);
wlr_viewporter_create(server->wl_display);
wlr_single_pixel_buffer_manager_v1_create(server->wl_display);
if (!server->security_context_manager_v1) {
sway_log(SWAY_ERROR, "Failed to create security context manager");
return false;
}
if (!wlr_viewporter_create(server->wl_display)) {
sway_log(SWAY_ERROR, "Failed to create viewporter");
return false;
}
if (!wlr_single_pixel_buffer_manager_v1_create(server->wl_display)) {
sway_log(SWAY_ERROR, "Failed to create single pixel buffer manager");
return false;
}
server->content_type_manager_v1 =
wlr_content_type_manager_v1_create(server->wl_display, 1);
wlr_fractional_scale_manager_v1_create(server->wl_display, 1);
if (!server->content_type_manager_v1) {
sway_log(SWAY_ERROR, "Failed to create content type manager");
return false;
}
if (!wlr_fractional_scale_manager_v1_create(server->wl_display, 1)) {
sway_log(SWAY_ERROR, "Failed to create fractional scale manager");
return false;
}
server->ext_foreign_toplevel_image_capture_source_manager_v1 =
wlr_ext_foreign_toplevel_image_capture_source_manager_v1_create(server->wl_display, 1);
if (!server->ext_foreign_toplevel_image_capture_source_manager_v1) {
sway_log(SWAY_ERROR, "Failed to create ext foreign toplevel image capture source manager");
return false;
}
server->new_foreign_toplevel_capture_request.notify = handle_new_foreign_toplevel_capture_request;
wl_signal_add(&server->ext_foreign_toplevel_image_capture_source_manager_v1->events.new_request,
&server->new_foreign_toplevel_capture_request);
server->tearing_control_v1 =
wlr_tearing_control_manager_v1_create(server->wl_display, 1);
if (!server->tearing_control_v1) {
sway_log(SWAY_ERROR, "Failed to create tearing control manager");
return false;
}
server->tearing_control_new_object.notify = handle_new_tearing_hint;
wl_signal_add(&server->tearing_control_v1->events.new_object,
&server->tearing_control_new_object);
@ -421,10 +577,24 @@ bool server_init(struct sway_server *server) {
struct wlr_xdg_foreign_registry *foreign_registry =
wlr_xdg_foreign_registry_create(server->wl_display);
wlr_xdg_foreign_v1_create(server->wl_display, foreign_registry);
wlr_xdg_foreign_v2_create(server->wl_display, foreign_registry);
if (!foreign_registry) {
sway_log(SWAY_ERROR, "Failed to create XDG foreign registry");
return false;
}
if (!wlr_xdg_foreign_v1_create(server->wl_display, foreign_registry)) {
sway_log(SWAY_ERROR, "Failed to create XDG foreign v1");
return false;
}
if (!wlr_xdg_foreign_v2_create(server->wl_display, foreign_registry)) {
sway_log(SWAY_ERROR, "Failed to create XDG foreign v2");
return false;
}
server->xdg_activation_v1 = wlr_xdg_activation_v1_create(server->wl_display);
if (!server->xdg_activation_v1) {
sway_log(SWAY_ERROR, "Failed to create XDG activation");
return false;
}
server->xdg_activation_v1_request_activate.notify =
xdg_activation_v1_handle_request_activate;
wl_signal_add(&server->xdg_activation_v1->events.request_activate,
@ -436,6 +606,10 @@ bool server_init(struct sway_server *server) {
struct wlr_xdg_toplevel_tag_manager_v1 *xdg_toplevel_tag_manager_v1 =
wlr_xdg_toplevel_tag_manager_v1_create(server->wl_display, 1);
if (!xdg_toplevel_tag_manager_v1) {
sway_log(SWAY_ERROR, "Failed to create XDG toplevel tag manager");
return false;
}
server->xdg_toplevel_tag_manager_v1_set_tag.notify =
xdg_toplevel_tag_manager_v1_handle_set_tag;
wl_signal_add(&xdg_toplevel_tag_manager_v1->events.set_tag,
@ -443,6 +617,10 @@ bool server_init(struct sway_server *server) {
struct wlr_cursor_shape_manager_v1 *cursor_shape_manager =
wlr_cursor_shape_manager_v1_create(server->wl_display, 2);
if (!cursor_shape_manager) {
sway_log(SWAY_ERROR, "Failed to create cursor shape manager");
return false;
}
server->request_set_cursor_shape.notify = handle_request_set_cursor_shape;
wl_signal_add(&cursor_shape_manager->events.request_set_shape, &server->request_set_cursor_shape);
@ -471,11 +649,18 @@ bool server_init(struct sway_server *server) {
});
free(transfer_functions);
free(primaries);
if (!cm) {
sway_log(SWAY_ERROR, "Failed to create color manager");
return false;
}
wlr_scene_set_color_manager_v1(root->root_scene, cm);
}
wlr_color_representation_manager_v1_create_with_renderer(
server->wl_display, 1, server->renderer);
if (!wlr_color_representation_manager_v1_create_with_renderer(
server->wl_display, 1, server->renderer)) {
sway_log(SWAY_ERROR, "Failed to create color representation manager");
return false;
}
wl_list_init(&server->pending_launcher_ctxs);
@ -515,8 +700,16 @@ bool server_init(struct sway_server *server) {
}
server->dirty_nodes = create_list();
if (!server->dirty_nodes) {
sway_log(SWAY_ERROR, "Failed to create dirty nodes list");
return false;
}
server->input = input_manager_create(server);
if (!server->input) {
sway_log(SWAY_ERROR, "Failed to create input manager");
return false;
}
input_manager_get_default_seat(); // create seat0
return true;

View file

@ -97,17 +97,18 @@ static void handle_commit(struct wl_listener *listener, void *data) {
}
// Initialize ext-workspace. Must be called once at startup.
void sway_ext_workspace_init(void) {
bool sway_ext_workspace_init(void) {
server.workspace_manager_v1 =
wlr_ext_workspace_manager_v1_create(server.wl_display, 1);
if (!server.workspace_manager_v1) {
sway_log(SWAY_ERROR, "Failed to create ext_workspace_manager_v1");
return;
return false;
}
server.workspace_manager_v1_commit.notify = handle_commit;
wl_signal_add(&server.workspace_manager_v1->events.commit,
&server.workspace_manager_v1_commit);
return true;
}
// Must be called whenever an output is enabled.