aboutsummaryrefslogtreecommitdiff
path: root/sway/config/bar.c
diff options
context:
space:
mode:
authorBrian Ashworth <bosrsf04@gmail.com>2019-05-11 23:14:01 -0400
committerSimon Ser <contact@emersion.fr>2019-05-12 11:02:42 +0300
commit18ce0eec608d066565dda3a9a6454f67007116e5 (patch)
tree2144ce9469726825392858b054c97ac46fa74e0c /sway/config/bar.c
parent8c8e6a6c9089d70c3b970b03c3f783eafd16f825 (diff)
Spawn swaybar as a wayland client
This just makes it so swaybar is handled as a wayland client
Diffstat (limited to 'sway/config/bar.c')
-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 @@
#define _POSIX_C_SOURCE 200809L
-#include <stdio.h>
+#include <signal.h>
#include <stdbool.h>
+#include <stdio.h>
#include <stdlib.h>
-#include <unistd.h>
-#include <wordexp.h>
+#include <strings.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
-#include <sys/stat.h>
-#include <signal.h>
-#include <strings.h>
-#include <signal.h>
+#include <unistd.h>
+#include <wordexp.h>
#include "sway/config.h"
#include "sway/input/keyboard.h"
#include "sway/output.h"
@@ -17,17 +17,7 @@
#include "list.h"
#include "log.h"
#include "stringop.h"
-
-static void terminate_swaybar(pid_t pid) {
- sway_log(SWAY_DEBUG, "Terminating swaybar %d", pid);
- int ret = kill(-pid, SIGTERM);
- if (ret != 0) {
- sway_log_errno(SWAY_ERROR, "Unable to terminate swaybar %d", pid);
- } else {
- int status;
- waitpid(pid, &status, 0);
- }
-}
+#include "util.h"
void free_bar_binding(struct bar_binding *binding) {
if (!binding) {
@@ -54,8 +44,8 @@ void free_bar_config(struct bar_config *bar) {
}
list_free(bar->bindings);
list_free_items_and_destroy(bar->outputs);
- if (bar->pid != 0) {
- terminate_swaybar(bar->pid);
+ if (bar->client != NULL) {
+ wl_client_destroy(bar->client);
}
free(bar->colors.background);
free(bar->colors.statusline);
@@ -110,7 +100,6 @@ struct bar_config *default_bar_config(void) {
bar->strip_workspace_name = false;
bar->binding_mode_indicator = true;
bar->verbose = false;
- bar->pid = 0;
bar->modifier = get_modifier_mask_by_name("Mod4");
bar->status_padding = 1;
bar->status_edge_padding = 3;
@@ -190,63 +179,84 @@ cleanup:
return NULL;
}
+static void handle_swaybar_client_destroy(struct wl_listener *listener,
+ void *data) {
+ struct bar_config *bar = wl_container_of(listener, bar, client_destroy);
+ wl_list_remove(&bar->client_destroy.link);
+ wl_list_init(&bar->client_destroy.link);
+ bar->client = NULL;
+}
+
static void invoke_swaybar(struct bar_config *bar) {
- // Pipe to communicate errors
- int filedes[2];
- if (pipe(filedes) == -1) {
- sway_log(SWAY_ERROR, "Pipe setup failed! Cannot fork into bar");
+ int sockets[2];
+ if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockets) != 0) {
+ sway_log_errno(SWAY_ERROR, "socketpair failed");
+ return;
+ }
+ if (!set_cloexec(sockets[0], true) || !set_cloexec(sockets[1], true)) {
+ return;
+ }
+
+ bar->client = wl_client_create(server.wl_display, sockets[0]);
+ if (bar->client == NULL) {
+ sway_log_errno(SWAY_ERROR, "wl_client_create failed");
return;
}
- bar->pid = fork();
- if (bar->pid == 0) {
- setpgid(0, 0);
- close(filedes[0]);
+ bar->client_destroy.notify = handle_swaybar_client_destroy;
+ wl_client_add_destroy_listener(bar->client, &bar->client_destroy);
+
+ pid_t pid = fork();
+ if (pid < 0) {
+ sway_log(SWAY_ERROR, "Failed to create fork for swaybar");
+ return;
+ } else if (pid == 0) {
+ // Remove the SIGUSR1 handler that wlroots adds for xwayland
sigset_t set;
sigemptyset(&set);
sigprocmask(SIG_SETMASK, &set, NULL);
- // run custom swaybar
- size_t len = snprintf(NULL, 0, "%s -b %s",
- bar->swaybar_command ? bar->swaybar_command : "swaybar",
- bar->id);
- char *command = malloc(len + 1);
- if (!command) {
- const char msg[] = "Unable to allocate swaybar command string";
- size_t msg_len = sizeof(msg);
- if (write(filedes[1], &msg_len, sizeof(size_t))) {};
- if (write(filedes[1], msg, msg_len)) {};
- close(filedes[1]);
- exit(1);
- }
- snprintf(command, len + 1, "%s -b %s",
- bar->swaybar_command ? bar->swaybar_command : "swaybar",
- bar->id);
- char *const cmd[] = { "sh", "-c", command, NULL, };
- close(filedes[1]);
- execvp(cmd[0], cmd);
- exit(1);
- }
- sway_log(SWAY_DEBUG, "Spawned swaybar %d", bar->pid);
- close(filedes[0]);
- size_t len;
- if (read(filedes[1], &len, sizeof(size_t)) == sizeof(size_t)) {
- char *buf = malloc(len);
- if(!buf) {
- sway_log(SWAY_ERROR, "Cannot allocate error string");
- return;
- }
- if (read(filedes[1], buf, len)) {
- sway_log(SWAY_ERROR, "%s", buf);
+ pid = fork();
+ if (pid < 0) {
+ sway_log_errno(SWAY_ERROR, "fork failed");
+ _exit(EXIT_FAILURE);
+ } else if (pid == 0) {
+ if (!set_cloexec(sockets[1], false)) {
+ _exit(EXIT_FAILURE);
+ }
+
+ char wayland_socket_str[16];
+ snprintf(wayland_socket_str, sizeof(wayland_socket_str),
+ "%d", sockets[1]);
+ setenv("WAYLAND_SOCKET", wayland_socket_str, true);
+
+ // run custom swaybar
+ char *const cmd[] = {
+ bar->swaybar_command ? bar->swaybar_command : "swaybar",
+ "-b", bar->id, NULL};
+ execvp(cmd[0], cmd);
+ _exit(EXIT_FAILURE);
}
- free(buf);
+ _exit(EXIT_SUCCESS);
+ }
+
+ if (close(sockets[1]) != 0) {
+ sway_log_errno(SWAY_ERROR, "close failed");
+ return;
}
- close(filedes[1]);
+
+ if (waitpid(pid, NULL, 0) < 0) {
+ sway_log_errno(SWAY_ERROR, "waitpid failed");
+ return;
+ }
+
+ sway_log(SWAY_DEBUG, "Spawned swaybar %s", bar->id);
+ return;
}
void load_swaybar(struct bar_config *bar) {
- if (bar->pid != 0) {
- terminate_swaybar(bar->pid);
+ if (bar->client != NULL) {
+ wl_client_destroy(bar->client);
}
sway_log(SWAY_DEBUG, "Invoking swaybar for bar id '%s'", bar->id);
invoke_swaybar(bar);