aboutsummaryrefslogtreecommitdiffstats
path: root/sway/config
diff options
context:
space:
mode:
authorLibravatar Brian Ashworth <bosrsf04@gmail.com>2019-05-11 23:14:01 -0400
committerLibravatar Simon Ser <contact@emersion.fr>2019-05-12 11:02:42 +0300
commit18ce0eec608d066565dda3a9a6454f67007116e5 (patch)
tree2144ce9469726825392858b054c97ac46fa74e0c /sway/config
parentconfig/output: fix typo in merge_id_on_name (diff)
downloadsway-18ce0eec608d066565dda3a9a6454f67007116e5.tar.gz
sway-18ce0eec608d066565dda3a9a6454f67007116e5.tar.zst
sway-18ce0eec608d066565dda3a9a6454f67007116e5.zip
Spawn swaybar as a wayland client
This just makes it so swaybar is handled as a wayland client
Diffstat (limited to 'sway/config')
-rw-r--r--sway/config/bar.c140
1 files changed, 75 insertions, 65 deletions
diff --git a/sway/config/bar.c b/sway/config/bar.c
index 2e28fa1e..4ab98ff1 100644
--- a/sway/config/bar.c
+++ b/sway/config/bar.c
@@ -1,15 +1,15 @@
1#define _POSIX_C_SOURCE 200809L 1#define _POSIX_C_SOURCE 200809L
2#include <stdio.h> 2#include <signal.h>
3#include <stdbool.h> 3#include <stdbool.h>
4#include <stdio.h>
4#include <stdlib.h> 5#include <stdlib.h>
5#include <unistd.h> 6#include <strings.h>
6#include <wordexp.h> 7#include <sys/socket.h>
8#include <sys/stat.h>
7#include <sys/types.h> 9#include <sys/types.h>
8#include <sys/wait.h> 10#include <sys/wait.h>
9#include <sys/stat.h> 11#include <unistd.h>
10#include <signal.h> 12#include <wordexp.h>
11#include <strings.h>
12#include <signal.h>
13#include "sway/config.h" 13#include "sway/config.h"
14#include "sway/input/keyboard.h" 14#include "sway/input/keyboard.h"
15#include "sway/output.h" 15#include "sway/output.h"
@@ -17,17 +17,7 @@
17#include "list.h" 17#include "list.h"
18#include "log.h" 18#include "log.h"
19#include "stringop.h" 19#include "stringop.h"
20 20#include "util.h"
21static void terminate_swaybar(pid_t pid) {
22 sway_log(SWAY_DEBUG, "Terminating swaybar %d", pid);
23 int ret = kill(-pid, SIGTERM);
24 if (ret != 0) {
25 sway_log_errno(SWAY_ERROR, "Unable to terminate swaybar %d", pid);
26 } else {
27 int status;
28 waitpid(pid, &status, 0);
29 }
30}
31 21
32void free_bar_binding(struct bar_binding *binding) { 22void free_bar_binding(struct bar_binding *binding) {
33 if (!binding) { 23 if (!binding) {
@@ -54,8 +44,8 @@ void free_bar_config(struct bar_config *bar) {
54 } 44 }
55 list_free(bar->bindings); 45 list_free(bar->bindings);
56 list_free_items_and_destroy(bar->outputs); 46 list_free_items_and_destroy(bar->outputs);
57 if (bar->pid != 0) { 47 if (bar->client != NULL) {
58 terminate_swaybar(bar->pid); 48 wl_client_destroy(bar->client);
59 } 49 }
60 free(bar->colors.background); 50 free(bar->colors.background);
61 free(bar->colors.statusline); 51 free(bar->colors.statusline);
@@ -110,7 +100,6 @@ struct bar_config *default_bar_config(void) {
110 bar->strip_workspace_name = false; 100 bar->strip_workspace_name = false;
111 bar->binding_mode_indicator = true; 101 bar->binding_mode_indicator = true;
112 bar->verbose = false; 102 bar->verbose = false;
113 bar->pid = 0;
114 bar->modifier = get_modifier_mask_by_name("Mod4"); 103 bar->modifier = get_modifier_mask_by_name("Mod4");
115 bar->status_padding = 1; 104 bar->status_padding = 1;
116 bar->status_edge_padding = 3; 105 bar->status_edge_padding = 3;
@@ -190,63 +179,84 @@ cleanup:
190 return NULL; 179 return NULL;
191} 180}
192 181
182static void handle_swaybar_client_destroy(struct wl_listener *listener,
183 void *data) {
184 struct bar_config *bar = wl_container_of(listener, bar, client_destroy);
185 wl_list_remove(&bar->client_destroy.link);
186 wl_list_init(&bar->client_destroy.link);
187 bar->client = NULL;
188}
189
193static void invoke_swaybar(struct bar_config *bar) { 190static void invoke_swaybar(struct bar_config *bar) {
194 // Pipe to communicate errors 191 int sockets[2];
195 int filedes[2]; 192 if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockets) != 0) {
196 if (pipe(filedes) == -1) { 193 sway_log_errno(SWAY_ERROR, "socketpair failed");
197 sway_log(SWAY_ERROR, "Pipe setup failed! Cannot fork into bar"); 194 return;
195 }
196 if (!set_cloexec(sockets[0], true) || !set_cloexec(sockets[1], true)) {
197 return;
198 }
199
200 bar->client = wl_client_create(server.wl_display, sockets[0]);
201 if (bar->client == NULL) {
202 sway_log_errno(SWAY_ERROR, "wl_client_create failed");
198 return; 203 return;
199 } 204 }
200 205
201 bar->pid = fork(); 206 bar->client_destroy.notify = handle_swaybar_client_destroy;
202 if (bar->pid == 0) { 207 wl_client_add_destroy_listener(bar->client, &bar->client_destroy);
203 setpgid(0, 0); 208
204 close(filedes[0]); 209 pid_t pid = fork();
210 if (pid < 0) {
211 sway_log(SWAY_ERROR, "Failed to create fork for swaybar");
212 return;
213 } else if (pid == 0) {
214 // Remove the SIGUSR1 handler that wlroots adds for xwayland
205 sigset_t set; 215 sigset_t set;
206 sigemptyset(&set); 216 sigemptyset(&set);
207 sigprocmask(SIG_SETMASK, &set, NULL); 217 sigprocmask(SIG_SETMASK, &set, NULL);
208 218
209 // run custom swaybar 219 pid = fork();
210 size_t len = snprintf(NULL, 0, "%s -b %s", 220 if (pid < 0) {
211 bar->swaybar_command ? bar->swaybar_command : "swaybar", 221 sway_log_errno(SWAY_ERROR, "fork failed");
212 bar->id); 222 _exit(EXIT_FAILURE);
213 char *command = malloc(len + 1); 223 } else if (pid == 0) {
214 if (!command) { 224 if (!set_cloexec(sockets[1], false)) {
215 const char msg[] = "Unable to allocate swaybar command string"; 225 _exit(EXIT_FAILURE);
216 size_t msg_len = sizeof(msg); 226 }
217 if (write(filedes[1], &msg_len, sizeof(size_t))) {}; 227
218 if (write(filedes[1], msg, msg_len)) {}; 228 char wayland_socket_str[16];
219 close(filedes[1]); 229 snprintf(wayland_socket_str, sizeof(wayland_socket_str),
220 exit(1); 230 "%d", sockets[1]);
221 } 231 setenv("WAYLAND_SOCKET", wayland_socket_str, true);
222 snprintf(command, len + 1, "%s -b %s", 232
223 bar->swaybar_command ? bar->swaybar_command : "swaybar", 233 // run custom swaybar
224 bar->id); 234 char *const cmd[] = {
225 char *const cmd[] = { "sh", "-c", command, NULL, }; 235 bar->swaybar_command ? bar->swaybar_command : "swaybar",
226 close(filedes[1]); 236 "-b", bar->id, NULL};
227 execvp(cmd[0], cmd); 237 execvp(cmd[0], cmd);
228 exit(1); 238 _exit(EXIT_FAILURE);
229 }
230 sway_log(SWAY_DEBUG, "Spawned swaybar %d", bar->pid);
231 close(filedes[0]);
232 size_t len;
233 if (read(filedes[1], &len, sizeof(size_t)) == sizeof(size_t)) {
234 char *buf = malloc(len);
235 if(!buf) {
236 sway_log(SWAY_ERROR, "Cannot allocate error string");
237 return;
238 }
239 if (read(filedes[1], buf, len)) {
240 sway_log(SWAY_ERROR, "%s", buf);
241 } 239 }
242 free(buf); 240 _exit(EXIT_SUCCESS);
241 }
242
243 if (close(sockets[1]) != 0) {
244 sway_log_errno(SWAY_ERROR, "close failed");
245 return;
243 } 246 }
244 close(filedes[1]); 247
248 if (waitpid(pid, NULL, 0) < 0) {
249 sway_log_errno(SWAY_ERROR, "waitpid failed");
250 return;
251 }
252
253 sway_log(SWAY_DEBUG, "Spawned swaybar %s", bar->id);
254 return;
245} 255}
246 256
247void load_swaybar(struct bar_config *bar) { 257void load_swaybar(struct bar_config *bar) {
248 if (bar->pid != 0) { 258 if (bar->client != NULL) {
249 terminate_swaybar(bar->pid); 259 wl_client_destroy(bar->client);
250 } 260 }
251 sway_log(SWAY_DEBUG, "Invoking swaybar for bar id '%s'", bar->id); 261 sway_log(SWAY_DEBUG, "Invoking swaybar for bar id '%s'", bar->id);
252 invoke_swaybar(bar); 262 invoke_swaybar(bar);