diff options
Diffstat (limited to 'sway')
-rw-r--r-- | sway/config/output.c | 91 | ||||
-rw-r--r-- | sway/desktop/output.c | 2 | ||||
-rw-r--r-- | sway/tree/output.c | 5 |
3 files changed, 76 insertions, 22 deletions
diff --git a/sway/config/output.c b/sway/config/output.c index 0f238715..513d03e0 100644 --- a/sway/config/output.c +++ b/sway/config/output.c | |||
@@ -1,16 +1,17 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | 1 | #define _POSIX_C_SOURCE 200809L |
2 | #include <assert.h> | 2 | #include <assert.h> |
3 | #include <fcntl.h> | ||
3 | #include <stdbool.h> | 4 | #include <stdbool.h> |
4 | #include <string.h> | 5 | #include <string.h> |
5 | #include <signal.h> | 6 | #include <sys/socket.h> |
6 | #include <sys/wait.h> | 7 | #include <sys/wait.h> |
7 | #include <unistd.h> | 8 | #include <unistd.h> |
8 | #include <wlr/types/wlr_output.h> | ||
9 | #include <wlr/types/wlr_output_layout.h> | 9 | #include <wlr/types/wlr_output_layout.h> |
10 | #include <wlr/types/wlr_output.h> | ||
11 | #include "log.h" | ||
10 | #include "sway/config.h" | 12 | #include "sway/config.h" |
11 | #include "sway/output.h" | 13 | #include "sway/output.h" |
12 | #include "sway/tree/root.h" | 14 | #include "sway/tree/root.h" |
13 | #include "log.h" | ||
14 | 15 | ||
15 | int output_name_cmp(const void *item, const void *data) { | 16 | int output_name_cmp(const void *item, const void *data) { |
16 | const struct output_config *output = item; | 17 | const struct output_config *output = item; |
@@ -165,14 +166,71 @@ static bool set_mode(struct wlr_output *output, int width, int height, | |||
165 | return wlr_output_set_mode(output, best); | 166 | return wlr_output_set_mode(output, best); |
166 | } | 167 | } |
167 | 168 | ||
168 | void terminate_swaybg(pid_t pid) { | 169 | static void handle_swaybg_client_destroy(struct wl_listener *listener, |
169 | int ret = kill(pid, SIGTERM); | 170 | void *data) { |
170 | if (ret != 0) { | 171 | struct sway_output *output = |
171 | sway_log(SWAY_ERROR, "Unable to terminate swaybg [pid: %d]", pid); | 172 | wl_container_of(listener, output, swaybg_client_destroy); |
172 | } else { | 173 | wl_list_remove(&output->swaybg_client_destroy.link); |
173 | int status; | 174 | wl_list_init(&output->swaybg_client_destroy.link); |
174 | waitpid(pid, &status, 0); | 175 | output->swaybg_client = NULL; |
176 | } | ||
177 | |||
178 | static bool spawn_swaybg(struct sway_output *output, char *const cmd[]) { | ||
179 | int sockets[2]; | ||
180 | if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, sockets) != 0) { | ||
181 | sway_log_errno(SWAY_ERROR, "socketpair failed"); | ||
182 | return false; | ||
183 | } | ||
184 | |||
185 | output->swaybg_client = wl_client_create(server.wl_display, sockets[0]); | ||
186 | if (output->swaybg_client == NULL) { | ||
187 | sway_log_errno(SWAY_ERROR, "wl_client_create failed"); | ||
188 | return false; | ||
189 | } | ||
190 | |||
191 | output->swaybg_client_destroy.notify = handle_swaybg_client_destroy; | ||
192 | wl_client_add_destroy_listener(output->swaybg_client, | ||
193 | &output->swaybg_client_destroy); | ||
194 | |||
195 | pid_t pid = fork(); | ||
196 | if (pid < 0) { | ||
197 | sway_log_errno(SWAY_ERROR, "fork failed"); | ||
198 | return false; | ||
199 | } else if (pid == 0) { | ||
200 | pid = fork(); | ||
201 | if (pid < 0) { | ||
202 | sway_log_errno(SWAY_ERROR, "fork failed"); | ||
203 | exit(EXIT_FAILURE); | ||
204 | } else if (pid == 0) { | ||
205 | // Remove the CLOEXEC flag | ||
206 | int flags = fcntl(sockets[1], F_GETFD); | ||
207 | if (flags == -1) { | ||
208 | sway_log_errno(SWAY_ERROR, "fcntl() failed"); | ||
209 | exit(EXIT_FAILURE); | ||
210 | } | ||
211 | if (fcntl(sockets[1], F_SETFD, flags & ~FD_CLOEXEC) == -1) { | ||
212 | sway_log_errno(SWAY_ERROR, "fcntl() failed"); | ||
213 | exit(EXIT_FAILURE); | ||
214 | } | ||
215 | |||
216 | char wayland_socket_str[16]; | ||
217 | snprintf(wayland_socket_str, sizeof(wayland_socket_str), | ||
218 | "%d", sockets[1]); | ||
219 | setenv("WAYLAND_SOCKET", wayland_socket_str, true); | ||
220 | |||
221 | execvp(cmd[0], cmd); | ||
222 | sway_log_errno(SWAY_ERROR, "execvp failed"); | ||
223 | exit(EXIT_FAILURE); | ||
224 | } | ||
225 | exit(EXIT_SUCCESS); | ||
175 | } | 226 | } |
227 | |||
228 | if (waitpid(pid, NULL, 0) < 0) { | ||
229 | sway_log_errno(SWAY_ERROR, "waitpid failed"); | ||
230 | return false; | ||
231 | } | ||
232 | |||
233 | return true; | ||
176 | } | 234 | } |
177 | 235 | ||
178 | bool apply_output_config(struct output_config *oc, struct sway_output *output) { | 236 | bool apply_output_config(struct output_config *oc, struct sway_output *output) { |
@@ -243,8 +301,8 @@ bool apply_output_config(struct output_config *oc, struct sway_output *output) { | |||
243 | wlr_output_layout_add_auto(root->output_layout, wlr_output); | 301 | wlr_output_layout_add_auto(root->output_layout, wlr_output); |
244 | } | 302 | } |
245 | 303 | ||
246 | if (output->bg_pid != 0) { | 304 | if (output->swaybg_client != NULL) { |
247 | terminate_swaybg(output->bg_pid); | 305 | wl_client_destroy(output->swaybg_client); |
248 | } | 306 | } |
249 | if (oc && oc->background && config->swaybg_command) { | 307 | if (oc && oc->background && config->swaybg_command) { |
250 | sway_log(SWAY_DEBUG, "Setting background for output %s to %s", | 308 | sway_log(SWAY_DEBUG, "Setting background for output %s to %s", |
@@ -258,13 +316,8 @@ bool apply_output_config(struct output_config *oc, struct sway_output *output) { | |||
258 | oc->background_fallback ? oc->background_fallback : NULL, | 316 | oc->background_fallback ? oc->background_fallback : NULL, |
259 | NULL, | 317 | NULL, |
260 | }; | 318 | }; |
261 | 319 | if (!spawn_swaybg(output, cmd)) { | |
262 | output->bg_pid = fork(); | 320 | return false; |
263 | if (output->bg_pid < 0) { | ||
264 | sway_log_errno(SWAY_ERROR, "fork failed"); | ||
265 | } else if (output->bg_pid == 0) { | ||
266 | execvp(cmd[0], cmd); | ||
267 | sway_log_errno(SWAY_ERROR, "Failed to execute swaybg"); | ||
268 | } | 321 | } |
269 | } | 322 | } |
270 | 323 | ||
diff --git a/sway/desktop/output.c b/sway/desktop/output.c index ad75bb35..c5461ee6 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c | |||
@@ -506,6 +506,7 @@ static void handle_destroy(struct wl_listener *listener, void *data) { | |||
506 | wl_list_remove(&output->present.link); | 506 | wl_list_remove(&output->present.link); |
507 | wl_list_remove(&output->damage_destroy.link); | 507 | wl_list_remove(&output->damage_destroy.link); |
508 | wl_list_remove(&output->damage_frame.link); | 508 | wl_list_remove(&output->damage_frame.link); |
509 | wl_list_remove(&output->swaybg_client_destroy.link); | ||
509 | 510 | ||
510 | transaction_commit_dirty(); | 511 | transaction_commit_dirty(); |
511 | } | 512 | } |
@@ -612,6 +613,7 @@ void handle_new_output(struct wl_listener *listener, void *data) { | |||
612 | output->damage_frame.notify = damage_handle_frame; | 613 | output->damage_frame.notify = damage_handle_frame; |
613 | wl_signal_add(&output->damage->events.destroy, &output->damage_destroy); | 614 | wl_signal_add(&output->damage->events.destroy, &output->damage_destroy); |
614 | output->damage_destroy.notify = damage_handle_destroy; | 615 | output->damage_destroy.notify = damage_handle_destroy; |
616 | wl_list_init(&output->swaybg_client_destroy.link); | ||
615 | 617 | ||
616 | struct output_config *oc = output_find_config(output); | 618 | struct output_config *oc = output_find_config(output); |
617 | if (!oc || oc->enabled) { | 619 | if (!oc || oc->enabled) { |
diff --git a/sway/tree/output.c b/sway/tree/output.c index 138144a7..60e0af9f 100644 --- a/sway/tree/output.c +++ b/sway/tree/output.c | |||
@@ -233,9 +233,8 @@ void output_disable(struct sway_output *output) { | |||
233 | 233 | ||
234 | root_for_each_container(untrack_output, output); | 234 | root_for_each_container(untrack_output, output); |
235 | 235 | ||
236 | if (output->bg_pid) { | 236 | if (output->swaybg_client != NULL) { |
237 | terminate_swaybg(output->bg_pid); | 237 | wl_client_destroy(output->swaybg_client); |
238 | output->bg_pid = 0; | ||
239 | } | 238 | } |
240 | 239 | ||
241 | int index = list_find(root->outputs, output); | 240 | int index = list_find(root->outputs, output); |