diff options
Diffstat (limited to 'sway/server.c')
-rw-r--r-- | sway/server.c | 244 |
1 files changed, 214 insertions, 30 deletions
diff --git a/sway/server.c b/sway/server.c index a87fc7cf..180d3a6b 100644 --- a/sway/server.c +++ b/sway/server.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <assert.h> | 1 | #include <assert.h> |
3 | #include <stdbool.h> | 2 | #include <stdbool.h> |
4 | #include <stdlib.h> | 3 | #include <stdlib.h> |
@@ -7,24 +6,34 @@ | |||
7 | #include <wlr/backend.h> | 6 | #include <wlr/backend.h> |
8 | #include <wlr/backend/headless.h> | 7 | #include <wlr/backend/headless.h> |
9 | #include <wlr/backend/multi.h> | 8 | #include <wlr/backend/multi.h> |
10 | #include <wlr/backend/session.h> | ||
11 | #include <wlr/config.h> | 9 | #include <wlr/config.h> |
10 | #include <wlr/render/allocator.h> | ||
12 | #include <wlr/render/wlr_renderer.h> | 11 | #include <wlr/render/wlr_renderer.h> |
13 | #include <wlr/types/wlr_compositor.h> | 12 | #include <wlr/types/wlr_compositor.h> |
13 | #include <wlr/types/wlr_content_type_v1.h> | ||
14 | #include <wlr/types/wlr_cursor_shape_v1.h> | ||
14 | #include <wlr/types/wlr_data_control_v1.h> | 15 | #include <wlr/types/wlr_data_control_v1.h> |
15 | #include <wlr/types/wlr_drm_lease_v1.h> | 16 | #include <wlr/types/wlr_data_device.h> |
16 | #include <wlr/types/wlr_drm.h> | 17 | #include <wlr/types/wlr_drm.h> |
17 | #include <wlr/types/wlr_export_dmabuf_v1.h> | 18 | #include <wlr/types/wlr_export_dmabuf_v1.h> |
19 | #include <wlr/types/wlr_ext_foreign_toplevel_list_v1.h> | ||
20 | #include <wlr/types/wlr_foreign_toplevel_management_v1.h> | ||
21 | #include <wlr/types/wlr_fractional_scale_v1.h> | ||
18 | #include <wlr/types/wlr_gamma_control_v1.h> | 22 | #include <wlr/types/wlr_gamma_control_v1.h> |
19 | #include <wlr/types/wlr_idle.h> | 23 | #include <wlr/types/wlr_idle_notify_v1.h> |
20 | #include <wlr/types/wlr_layer_shell_v1.h> | 24 | #include <wlr/types/wlr_layer_shell_v1.h> |
21 | #include <wlr/types/wlr_linux_dmabuf_v1.h> | 25 | #include <wlr/types/wlr_linux_dmabuf_v1.h> |
26 | #include <wlr/types/wlr_output_management_v1.h> | ||
27 | #include <wlr/types/wlr_output_power_management_v1.h> | ||
22 | #include <wlr/types/wlr_pointer_constraints_v1.h> | 28 | #include <wlr/types/wlr_pointer_constraints_v1.h> |
29 | #include <wlr/types/wlr_presentation_time.h> | ||
23 | #include <wlr/types/wlr_primary_selection_v1.h> | 30 | #include <wlr/types/wlr_primary_selection_v1.h> |
24 | #include <wlr/types/wlr_relative_pointer_v1.h> | 31 | #include <wlr/types/wlr_relative_pointer_v1.h> |
25 | #include <wlr/types/wlr_screencopy_v1.h> | 32 | #include <wlr/types/wlr_screencopy_v1.h> |
26 | #include <wlr/types/wlr_single_pixel_buffer_v1.h> | 33 | #include <wlr/types/wlr_security_context_v1.h> |
27 | #include <wlr/types/wlr_server_decoration.h> | 34 | #include <wlr/types/wlr_server_decoration.h> |
35 | #include <wlr/types/wlr_session_lock_v1.h> | ||
36 | #include <wlr/types/wlr_single_pixel_buffer_v1.h> | ||
28 | #include <wlr/types/wlr_subcompositor.h> | 37 | #include <wlr/types/wlr_subcompositor.h> |
29 | #include <wlr/types/wlr_tablet_v2.h> | 38 | #include <wlr/types/wlr_tablet_v2.h> |
30 | #include <wlr/types/wlr_viewporter.h> | 39 | #include <wlr/types/wlr_viewporter.h> |
@@ -35,6 +44,7 @@ | |||
35 | #include <wlr/types/wlr_xdg_foreign_v1.h> | 44 | #include <wlr/types/wlr_xdg_foreign_v1.h> |
36 | #include <wlr/types/wlr_xdg_foreign_v2.h> | 45 | #include <wlr/types/wlr_xdg_foreign_v2.h> |
37 | #include <wlr/types/wlr_xdg_output_v1.h> | 46 | #include <wlr/types/wlr_xdg_output_v1.h> |
47 | #include <xf86drm.h> | ||
38 | #include "config.h" | 48 | #include "config.h" |
39 | #include "list.h" | 49 | #include "list.h" |
40 | #include "log.h" | 50 | #include "log.h" |
@@ -43,11 +53,25 @@ | |||
43 | #include "sway/input/input-manager.h" | 53 | #include "sway/input/input-manager.h" |
44 | #include "sway/output.h" | 54 | #include "sway/output.h" |
45 | #include "sway/server.h" | 55 | #include "sway/server.h" |
56 | #include "sway/input/cursor.h" | ||
46 | #include "sway/tree/root.h" | 57 | #include "sway/tree/root.h" |
58 | |||
47 | #if HAVE_XWAYLAND | 59 | #if HAVE_XWAYLAND |
60 | #include <wlr/xwayland/shell.h> | ||
48 | #include "sway/xwayland.h" | 61 | #include "sway/xwayland.h" |
49 | #endif | 62 | #endif |
50 | 63 | ||
64 | #if WLR_HAS_DRM_BACKEND | ||
65 | #include <wlr/types/wlr_drm_lease_v1.h> | ||
66 | #endif | ||
67 | |||
68 | #define SWAY_XDG_SHELL_VERSION 5 | ||
69 | #define SWAY_LAYER_SHELL_VERSION 4 | ||
70 | #define SWAY_FOREIGN_TOPLEVEL_LIST_VERSION 1 | ||
71 | |||
72 | bool allow_unsupported_gpu = false; | ||
73 | |||
74 | #if WLR_HAS_DRM_BACKEND | ||
51 | static void handle_drm_lease_request(struct wl_listener *listener, void *data) { | 75 | static void handle_drm_lease_request(struct wl_listener *listener, void *data) { |
52 | /* We only offer non-desktop outputs, but in the future we might want to do | 76 | /* We only offer non-desktop outputs, but in the future we might want to do |
53 | * more logic here. */ | 77 | * more logic here. */ |
@@ -59,32 +83,169 @@ static void handle_drm_lease_request(struct wl_listener *listener, void *data) { | |||
59 | wlr_drm_lease_request_v1_reject(req); | 83 | wlr_drm_lease_request_v1_reject(req); |
60 | } | 84 | } |
61 | } | 85 | } |
86 | #endif | ||
87 | |||
88 | static bool is_privileged(const struct wl_global *global) { | ||
89 | #if WLR_HAS_DRM_BACKEND | ||
90 | if (server.drm_lease_manager != NULL) { | ||
91 | struct wlr_drm_lease_device_v1 *drm_lease_dev; | ||
92 | wl_list_for_each(drm_lease_dev, &server.drm_lease_manager->devices, link) { | ||
93 | if (drm_lease_dev->global == global) { | ||
94 | return true; | ||
95 | } | ||
96 | } | ||
97 | } | ||
98 | #endif | ||
99 | |||
100 | return | ||
101 | global == server.output_manager_v1->global || | ||
102 | global == server.output_power_manager_v1->global || | ||
103 | global == server.input_method->global || | ||
104 | global == server.foreign_toplevel_list->global || | ||
105 | global == server.foreign_toplevel_manager->global || | ||
106 | global == server.data_control_manager_v1->global || | ||
107 | global == server.screencopy_manager_v1->global || | ||
108 | global == server.export_dmabuf_manager_v1->global || | ||
109 | global == server.security_context_manager_v1->global || | ||
110 | global == server.gamma_control_manager_v1->global || | ||
111 | global == server.layer_shell->global || | ||
112 | global == server.session_lock.manager->global || | ||
113 | global == server.input->keyboard_shortcuts_inhibit->global || | ||
114 | global == server.input->virtual_keyboard->global || | ||
115 | global == server.input->virtual_pointer->global || | ||
116 | global == server.input->transient_seat_manager->global; | ||
117 | } | ||
118 | |||
119 | static bool filter_global(const struct wl_client *client, | ||
120 | const struct wl_global *global, void *data) { | ||
121 | #if HAVE_XWAYLAND | ||
122 | struct wlr_xwayland *xwayland = server.xwayland.wlr_xwayland; | ||
123 | if (xwayland && global == xwayland->shell_v1->global) { | ||
124 | return xwayland->server != NULL && client == xwayland->server->client; | ||
125 | } | ||
126 | #endif | ||
127 | |||
128 | // Restrict usage of privileged protocols to unsandboxed clients | ||
129 | // TODO: add a way for users to configure an allow-list | ||
130 | const struct wlr_security_context_v1_state *security_context = | ||
131 | wlr_security_context_manager_v1_lookup_client( | ||
132 | server.security_context_manager_v1, (struct wl_client *)client); | ||
133 | if (is_privileged(global)) { | ||
134 | return security_context == NULL; | ||
135 | } | ||
136 | |||
137 | return true; | ||
138 | } | ||
139 | |||
140 | static void detect_proprietary(struct wlr_backend *backend, void *data) { | ||
141 | int drm_fd = wlr_backend_get_drm_fd(backend); | ||
142 | if (drm_fd < 0) { | ||
143 | return; | ||
144 | } | ||
145 | |||
146 | drmVersion *version = drmGetVersion(drm_fd); | ||
147 | if (version == NULL) { | ||
148 | sway_log(SWAY_ERROR, "drmGetVersion() failed"); | ||
149 | return; | ||
150 | } | ||
151 | |||
152 | bool is_unsupported = false; | ||
153 | if (strcmp(version->name, "nvidia-drm") == 0) { | ||
154 | is_unsupported = true; | ||
155 | sway_log(SWAY_ERROR, "!!! Proprietary Nvidia drivers are in use !!!"); | ||
156 | if (!allow_unsupported_gpu) { | ||
157 | sway_log(SWAY_ERROR, "Use Nouveau instead"); | ||
158 | } | ||
159 | } | ||
160 | |||
161 | if (strcmp(version->name, "evdi") == 0) { | ||
162 | is_unsupported = true; | ||
163 | sway_log(SWAY_ERROR, "!!! Proprietary DisplayLink drivers are in use !!!"); | ||
164 | } | ||
165 | |||
166 | if (!allow_unsupported_gpu && is_unsupported) { | ||
167 | sway_log(SWAY_ERROR, | ||
168 | "Proprietary drivers are NOT supported. To launch sway anyway, " | ||
169 | "launch with --unsupported-gpu and DO NOT report issues."); | ||
170 | exit(EXIT_FAILURE); | ||
171 | } | ||
172 | |||
173 | drmFreeVersion(version); | ||
174 | } | ||
175 | |||
176 | static void handle_renderer_lost(struct wl_listener *listener, void *data) { | ||
177 | struct sway_server *server = wl_container_of(listener, server, renderer_lost); | ||
178 | |||
179 | sway_log(SWAY_INFO, "Re-creating renderer after GPU reset"); | ||
180 | |||
181 | struct wlr_renderer *renderer = wlr_renderer_autocreate(server->backend); | ||
182 | if (renderer == NULL) { | ||
183 | sway_log(SWAY_ERROR, "Unable to create renderer"); | ||
184 | return; | ||
185 | } | ||
186 | |||
187 | struct wlr_allocator *allocator = | ||
188 | wlr_allocator_autocreate(server->backend, renderer); | ||
189 | if (allocator == NULL) { | ||
190 | sway_log(SWAY_ERROR, "Unable to create allocator"); | ||
191 | wlr_renderer_destroy(renderer); | ||
192 | return; | ||
193 | } | ||
194 | |||
195 | struct wlr_renderer *old_renderer = server->renderer; | ||
196 | struct wlr_allocator *old_allocator = server->allocator; | ||
197 | server->renderer = renderer; | ||
198 | server->allocator = allocator; | ||
62 | 199 | ||
63 | #define SWAY_XDG_SHELL_VERSION 2 | 200 | wl_list_remove(&server->renderer_lost.link); |
201 | wl_signal_add(&server->renderer->events.lost, &server->renderer_lost); | ||
202 | |||
203 | wlr_compositor_set_renderer(server->compositor, renderer); | ||
204 | |||
205 | for (int i = 0; i < root->outputs->length; ++i) { | ||
206 | struct sway_output *output = root->outputs->items[i]; | ||
207 | wlr_output_init_render(output->wlr_output, | ||
208 | server->allocator, server->renderer); | ||
209 | } | ||
210 | |||
211 | wlr_allocator_destroy(old_allocator); | ||
212 | wlr_renderer_destroy(old_renderer); | ||
213 | } | ||
64 | 214 | ||
65 | bool server_init(struct sway_server *server) { | 215 | bool server_init(struct sway_server *server) { |
66 | sway_log(SWAY_DEBUG, "Initializing Wayland server"); | 216 | sway_log(SWAY_DEBUG, "Initializing Wayland server"); |
67 | server->wl_display = wl_display_create(); | 217 | server->wl_display = wl_display_create(); |
68 | server->wl_event_loop = wl_display_get_event_loop(server->wl_display); | 218 | server->wl_event_loop = wl_display_get_event_loop(server->wl_display); |
69 | server->backend = wlr_backend_autocreate(server->wl_display); | ||
70 | 219 | ||
220 | wl_display_set_global_filter(server->wl_display, filter_global, NULL); | ||
221 | |||
222 | root = root_create(server->wl_display); | ||
223 | |||
224 | server->backend = wlr_backend_autocreate(server->wl_event_loop, &server->session); | ||
71 | if (!server->backend) { | 225 | if (!server->backend) { |
72 | sway_log(SWAY_ERROR, "Unable to create backend"); | 226 | sway_log(SWAY_ERROR, "Unable to create backend"); |
73 | return false; | 227 | return false; |
74 | } | 228 | } |
75 | 229 | ||
230 | wlr_multi_for_each_backend(server->backend, detect_proprietary, NULL); | ||
231 | |||
76 | server->renderer = wlr_renderer_autocreate(server->backend); | 232 | server->renderer = wlr_renderer_autocreate(server->backend); |
77 | if (!server->renderer) { | 233 | if (!server->renderer) { |
78 | sway_log(SWAY_ERROR, "Failed to create renderer"); | 234 | sway_log(SWAY_ERROR, "Failed to create renderer"); |
79 | return false; | 235 | return false; |
80 | } | 236 | } |
81 | 237 | ||
238 | server->renderer_lost.notify = handle_renderer_lost; | ||
239 | wl_signal_add(&server->renderer->events.lost, &server->renderer_lost); | ||
240 | |||
82 | wlr_renderer_init_wl_shm(server->renderer, server->wl_display); | 241 | wlr_renderer_init_wl_shm(server->renderer, server->wl_display); |
83 | 242 | ||
84 | if (wlr_renderer_get_dmabuf_texture_formats(server->renderer) != NULL) { | 243 | if (wlr_renderer_get_texture_formats(server->renderer, WLR_BUFFER_CAP_DMABUF) != NULL) { |
85 | wlr_drm_create(server->wl_display, server->renderer); | 244 | server->linux_dmabuf_v1 = wlr_linux_dmabuf_v1_create_with_renderer( |
86 | server->linux_dmabuf_v1 = | 245 | server->wl_display, 4, server->renderer); |
87 | wlr_linux_dmabuf_v1_create(server->wl_display, server->renderer); | 246 | if (debug.legacy_wl_drm) { |
247 | wlr_drm_create(server->wl_display, server->renderer); | ||
248 | } | ||
88 | } | 249 | } |
89 | 250 | ||
90 | server->allocator = wlr_allocator_autocreate(server->backend, | 251 | server->allocator = wlr_allocator_autocreate(server->backend, |
@@ -94,18 +255,19 @@ bool server_init(struct sway_server *server) { | |||
94 | return false; | 255 | return false; |
95 | } | 256 | } |
96 | 257 | ||
97 | server->compositor = wlr_compositor_create(server->wl_display, | 258 | server->compositor = wlr_compositor_create(server->wl_display, 6, |
98 | server->renderer); | 259 | server->renderer); |
99 | server->compositor_new_surface.notify = handle_compositor_new_surface; | ||
100 | wl_signal_add(&server->compositor->events.new_surface, | ||
101 | &server->compositor_new_surface); | ||
102 | 260 | ||
103 | wlr_subcompositor_create(server->wl_display); | 261 | wlr_subcompositor_create(server->wl_display); |
104 | 262 | ||
105 | server->data_device_manager = | 263 | server->data_device_manager = |
106 | wlr_data_device_manager_create(server->wl_display); | 264 | wlr_data_device_manager_create(server->wl_display); |
107 | 265 | ||
108 | wlr_gamma_control_manager_v1_create(server->wl_display); | 266 | server->gamma_control_manager_v1 = |
267 | wlr_gamma_control_manager_v1_create(server->wl_display); | ||
268 | server->gamma_control_set_gamma.notify = handle_gamma_control_set_gamma; | ||
269 | wl_signal_add(&server->gamma_control_manager_v1->events.set_gamma, | ||
270 | &server->gamma_control_set_gamma); | ||
109 | 271 | ||
110 | server->new_output.notify = handle_new_output; | 272 | server->new_output.notify = handle_new_output; |
111 | wl_signal_add(&server->backend->events.new_output, &server->new_output); | 273 | wl_signal_add(&server->backend->events.new_output, &server->new_output); |
@@ -115,20 +277,20 @@ bool server_init(struct sway_server *server) { | |||
115 | 277 | ||
116 | wlr_xdg_output_manager_v1_create(server->wl_display, root->output_layout); | 278 | wlr_xdg_output_manager_v1_create(server->wl_display, root->output_layout); |
117 | 279 | ||
118 | server->idle = wlr_idle_create(server->wl_display); | 280 | server->idle_notifier_v1 = wlr_idle_notifier_v1_create(server->wl_display); |
119 | server->idle_inhibit_manager_v1 = | 281 | sway_idle_inhibit_manager_v1_init(); |
120 | sway_idle_inhibit_manager_v1_create(server->wl_display, server->idle); | ||
121 | 282 | ||
122 | server->layer_shell = wlr_layer_shell_v1_create(server->wl_display); | 283 | server->layer_shell = wlr_layer_shell_v1_create(server->wl_display, |
284 | SWAY_LAYER_SHELL_VERSION); | ||
123 | wl_signal_add(&server->layer_shell->events.new_surface, | 285 | wl_signal_add(&server->layer_shell->events.new_surface, |
124 | &server->layer_shell_surface); | 286 | &server->layer_shell_surface); |
125 | server->layer_shell_surface.notify = handle_layer_shell_surface; | 287 | server->layer_shell_surface.notify = handle_layer_shell_surface; |
126 | 288 | ||
127 | server->xdg_shell = wlr_xdg_shell_create(server->wl_display, | 289 | server->xdg_shell = wlr_xdg_shell_create(server->wl_display, |
128 | SWAY_XDG_SHELL_VERSION); | 290 | SWAY_XDG_SHELL_VERSION); |
129 | wl_signal_add(&server->xdg_shell->events.new_surface, | 291 | wl_signal_add(&server->xdg_shell->events.new_toplevel, |
130 | &server->xdg_shell_surface); | 292 | &server->xdg_shell_toplevel); |
131 | server->xdg_shell_surface.notify = handle_xdg_shell_surface; | 293 | server->xdg_shell_toplevel.notify = handle_xdg_shell_toplevel; |
132 | 294 | ||
133 | server->tablet_v2 = wlr_tablet_v2_create(server->wl_display); | 295 | server->tablet_v2 = wlr_tablet_v2_create(server->wl_display); |
134 | 296 | ||
@@ -159,8 +321,7 @@ bool server_init(struct sway_server *server) { | |||
159 | wl_signal_add(&server->pointer_constraints->events.new_constraint, | 321 | wl_signal_add(&server->pointer_constraints->events.new_constraint, |
160 | &server->pointer_constraint); | 322 | &server->pointer_constraint); |
161 | 323 | ||
162 | server->presentation = | 324 | wlr_presentation_create(server->wl_display, server->backend); |
163 | wlr_presentation_create(server->wl_display, server->backend); | ||
164 | 325 | ||
165 | server->output_manager_v1 = | 326 | server->output_manager_v1 = |
166 | wlr_output_manager_v1_create(server->wl_display); | 327 | wlr_output_manager_v1_create(server->wl_display); |
@@ -179,11 +340,14 @@ bool server_init(struct sway_server *server) { | |||
179 | &server->output_power_manager_set_mode); | 340 | &server->output_power_manager_set_mode); |
180 | server->input_method = wlr_input_method_manager_v2_create(server->wl_display); | 341 | server->input_method = wlr_input_method_manager_v2_create(server->wl_display); |
181 | server->text_input = wlr_text_input_manager_v3_create(server->wl_display); | 342 | server->text_input = wlr_text_input_manager_v3_create(server->wl_display); |
343 | server->foreign_toplevel_list = | ||
344 | wlr_ext_foreign_toplevel_list_v1_create(server->wl_display, SWAY_FOREIGN_TOPLEVEL_LIST_VERSION); | ||
182 | server->foreign_toplevel_manager = | 345 | server->foreign_toplevel_manager = |
183 | wlr_foreign_toplevel_manager_v1_create(server->wl_display); | 346 | wlr_foreign_toplevel_manager_v1_create(server->wl_display); |
184 | 347 | ||
185 | sway_session_lock_init(); | 348 | sway_session_lock_init(); |
186 | 349 | ||
350 | #if WLR_HAS_DRM_BACKEND | ||
187 | server->drm_lease_manager= | 351 | server->drm_lease_manager= |
188 | wlr_drm_lease_v1_manager_create(server->wl_display, server->backend); | 352 | wlr_drm_lease_v1_manager_create(server->wl_display, server->backend); |
189 | if (server->drm_lease_manager) { | 353 | if (server->drm_lease_manager) { |
@@ -194,13 +358,17 @@ bool server_init(struct sway_server *server) { | |||
194 | sway_log(SWAY_DEBUG, "Failed to create wlr_drm_lease_device_v1"); | 358 | sway_log(SWAY_DEBUG, "Failed to create wlr_drm_lease_device_v1"); |
195 | sway_log(SWAY_INFO, "VR will not be available"); | 359 | sway_log(SWAY_INFO, "VR will not be available"); |
196 | } | 360 | } |
361 | #endif | ||
197 | 362 | ||
198 | wlr_export_dmabuf_manager_v1_create(server->wl_display); | 363 | server->export_dmabuf_manager_v1 = wlr_export_dmabuf_manager_v1_create(server->wl_display); |
199 | wlr_screencopy_manager_v1_create(server->wl_display); | 364 | server->screencopy_manager_v1 = wlr_screencopy_manager_v1_create(server->wl_display); |
200 | wlr_data_control_manager_v1_create(server->wl_display); | 365 | server->data_control_manager_v1 = wlr_data_control_manager_v1_create(server->wl_display); |
201 | wlr_primary_selection_v1_device_manager_create(server->wl_display); | 366 | server->security_context_manager_v1 = wlr_security_context_manager_v1_create(server->wl_display); |
202 | wlr_viewporter_create(server->wl_display); | 367 | wlr_viewporter_create(server->wl_display); |
203 | wlr_single_pixel_buffer_manager_v1_create(server->wl_display); | 368 | wlr_single_pixel_buffer_manager_v1_create(server->wl_display); |
369 | server->content_type_manager_v1 = | ||
370 | wlr_content_type_manager_v1_create(server->wl_display, 1); | ||
371 | wlr_fractional_scale_manager_v1_create(server->wl_display, 1); | ||
204 | 372 | ||
205 | struct wlr_xdg_foreign_registry *foreign_registry = | 373 | struct wlr_xdg_foreign_registry *foreign_registry = |
206 | wlr_xdg_foreign_registry_create(server->wl_display); | 374 | wlr_xdg_foreign_registry_create(server->wl_display); |
@@ -212,6 +380,17 @@ bool server_init(struct sway_server *server) { | |||
212 | xdg_activation_v1_handle_request_activate; | 380 | xdg_activation_v1_handle_request_activate; |
213 | wl_signal_add(&server->xdg_activation_v1->events.request_activate, | 381 | wl_signal_add(&server->xdg_activation_v1->events.request_activate, |
214 | &server->xdg_activation_v1_request_activate); | 382 | &server->xdg_activation_v1_request_activate); |
383 | server->xdg_activation_v1_new_token.notify = | ||
384 | xdg_activation_v1_handle_new_token; | ||
385 | wl_signal_add(&server->xdg_activation_v1->events.new_token, | ||
386 | &server->xdg_activation_v1_new_token); | ||
387 | |||
388 | struct wlr_cursor_shape_manager_v1 *cursor_shape_manager = | ||
389 | wlr_cursor_shape_manager_v1_create(server->wl_display, 1); | ||
390 | server->request_set_cursor_shape.notify = handle_request_set_cursor_shape; | ||
391 | wl_signal_add(&cursor_shape_manager->events.request_set_shape, &server->request_set_cursor_shape); | ||
392 | |||
393 | wl_list_init(&server->pending_launcher_ctxs); | ||
215 | 394 | ||
216 | // Avoid using "wayland-0" as display socket | 395 | // Avoid using "wayland-0" as display socket |
217 | char name_candidate[16]; | 396 | char name_candidate[16]; |
@@ -229,7 +408,7 @@ bool server_init(struct sway_server *server) { | |||
229 | return false; | 408 | return false; |
230 | } | 409 | } |
231 | 410 | ||
232 | server->headless_backend = wlr_headless_backend_create(server->wl_display); | 411 | server->headless_backend = wlr_headless_backend_create(server->wl_event_loop); |
233 | if (!server->headless_backend) { | 412 | if (!server->headless_backend) { |
234 | sway_log(SWAY_ERROR, "Failed to create secondary headless backend"); | 413 | sway_log(SWAY_ERROR, "Failed to create secondary headless backend"); |
235 | wlr_backend_destroy(server->backend); | 414 | wlr_backend_destroy(server->backend); |
@@ -262,6 +441,7 @@ void server_fini(struct sway_server *server) { | |||
262 | wlr_xwayland_destroy(server->xwayland.wlr_xwayland); | 441 | wlr_xwayland_destroy(server->xwayland.wlr_xwayland); |
263 | #endif | 442 | #endif |
264 | wl_display_destroy_clients(server->wl_display); | 443 | wl_display_destroy_clients(server->wl_display); |
444 | wlr_backend_destroy(server->backend); | ||
265 | wl_display_destroy(server->wl_display); | 445 | wl_display_destroy(server->wl_display); |
266 | list_free(server->dirty_nodes); | 446 | list_free(server->dirty_nodes); |
267 | } | 447 | } |
@@ -292,6 +472,10 @@ bool server_start(struct sway_server *server) { | |||
292 | } | 472 | } |
293 | #endif | 473 | #endif |
294 | 474 | ||
475 | if (config->primary_selection) { | ||
476 | wlr_primary_selection_v1_device_manager_create(server->wl_display); | ||
477 | } | ||
478 | |||
295 | sway_log(SWAY_INFO, "Starting backend on wayland display '%s'", | 479 | sway_log(SWAY_INFO, "Starting backend on wayland display '%s'", |
296 | server->socket); | 480 | server->socket); |
297 | if (!wlr_backend_start(server->backend)) { | 481 | if (!wlr_backend_start(server->backend)) { |