Spawn swaybar as a wayland client
This just makes it so swaybar is handled as a wayland client
This commit is contained in:
parent
8c8e6a6c90
commit
18ce0eec60
|
@ -216,6 +216,10 @@ struct workspace_config {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct bar_config {
|
struct bar_config {
|
||||||
|
char *swaybar_command;
|
||||||
|
struct wl_client *client;
|
||||||
|
struct wl_listener client_destroy;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* One of "dock", "hide", "invisible"
|
* One of "dock", "hide", "invisible"
|
||||||
*
|
*
|
||||||
|
@ -243,7 +247,6 @@ struct bar_config {
|
||||||
list_t *bindings;
|
list_t *bindings;
|
||||||
char *status_command;
|
char *status_command;
|
||||||
bool pango_markup;
|
bool pango_markup;
|
||||||
char *swaybar_command;
|
|
||||||
char *font;
|
char *font;
|
||||||
int height; // -1 not defined
|
int height; // -1 not defined
|
||||||
bool workspace_buttons;
|
bool workspace_buttons;
|
||||||
|
@ -254,7 +257,6 @@ struct bar_config {
|
||||||
bool binding_mode_indicator;
|
bool binding_mode_indicator;
|
||||||
bool verbose;
|
bool verbose;
|
||||||
struct side_gaps gaps;
|
struct side_gaps gaps;
|
||||||
pid_t pid;
|
|
||||||
int status_padding;
|
int status_padding;
|
||||||
int status_edge_padding;
|
int status_edge_padding;
|
||||||
struct {
|
struct {
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
#define _POSIX_C_SOURCE 200809L
|
#define _POSIX_C_SOURCE 200809L
|
||||||
#include <stdio.h>
|
#include <signal.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <strings.h>
|
||||||
#include <wordexp.h>
|
#include <sys/socket.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <sys/stat.h>
|
#include <unistd.h>
|
||||||
#include <signal.h>
|
#include <wordexp.h>
|
||||||
#include <strings.h>
|
|
||||||
#include <signal.h>
|
|
||||||
#include "sway/config.h"
|
#include "sway/config.h"
|
||||||
#include "sway/input/keyboard.h"
|
#include "sway/input/keyboard.h"
|
||||||
#include "sway/output.h"
|
#include "sway/output.h"
|
||||||
|
@ -17,17 +17,7 @@
|
||||||
#include "list.h"
|
#include "list.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "stringop.h"
|
#include "stringop.h"
|
||||||
|
#include "util.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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void free_bar_binding(struct bar_binding *binding) {
|
void free_bar_binding(struct bar_binding *binding) {
|
||||||
if (!binding) {
|
if (!binding) {
|
||||||
|
@ -54,8 +44,8 @@ void free_bar_config(struct bar_config *bar) {
|
||||||
}
|
}
|
||||||
list_free(bar->bindings);
|
list_free(bar->bindings);
|
||||||
list_free_items_and_destroy(bar->outputs);
|
list_free_items_and_destroy(bar->outputs);
|
||||||
if (bar->pid != 0) {
|
if (bar->client != NULL) {
|
||||||
terminate_swaybar(bar->pid);
|
wl_client_destroy(bar->client);
|
||||||
}
|
}
|
||||||
free(bar->colors.background);
|
free(bar->colors.background);
|
||||||
free(bar->colors.statusline);
|
free(bar->colors.statusline);
|
||||||
|
@ -110,7 +100,6 @@ struct bar_config *default_bar_config(void) {
|
||||||
bar->strip_workspace_name = false;
|
bar->strip_workspace_name = false;
|
||||||
bar->binding_mode_indicator = true;
|
bar->binding_mode_indicator = true;
|
||||||
bar->verbose = false;
|
bar->verbose = false;
|
||||||
bar->pid = 0;
|
|
||||||
bar->modifier = get_modifier_mask_by_name("Mod4");
|
bar->modifier = get_modifier_mask_by_name("Mod4");
|
||||||
bar->status_padding = 1;
|
bar->status_padding = 1;
|
||||||
bar->status_edge_padding = 3;
|
bar->status_edge_padding = 3;
|
||||||
|
@ -190,63 +179,84 @@ cleanup:
|
||||||
return NULL;
|
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) {
|
static void invoke_swaybar(struct bar_config *bar) {
|
||||||
// Pipe to communicate errors
|
int sockets[2];
|
||||||
int filedes[2];
|
if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockets) != 0) {
|
||||||
if (pipe(filedes) == -1) {
|
sway_log_errno(SWAY_ERROR, "socketpair failed");
|
||||||
sway_log(SWAY_ERROR, "Pipe setup failed! Cannot fork into bar");
|
return;
|
||||||
|
}
|
||||||
|
if (!set_cloexec(sockets[0], true) || !set_cloexec(sockets[1], true)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bar->pid = fork();
|
bar->client = wl_client_create(server.wl_display, sockets[0]);
|
||||||
if (bar->pid == 0) {
|
if (bar->client == NULL) {
|
||||||
setpgid(0, 0);
|
sway_log_errno(SWAY_ERROR, "wl_client_create failed");
|
||||||
close(filedes[0]);
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
sigset_t set;
|
||||||
sigemptyset(&set);
|
sigemptyset(&set);
|
||||||
sigprocmask(SIG_SETMASK, &set, NULL);
|
sigprocmask(SIG_SETMASK, &set, NULL);
|
||||||
|
|
||||||
|
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
|
// run custom swaybar
|
||||||
size_t len = snprintf(NULL, 0, "%s -b %s",
|
char *const cmd[] = {
|
||||||
bar->swaybar_command ? bar->swaybar_command : "swaybar",
|
bar->swaybar_command ? bar->swaybar_command : "swaybar",
|
||||||
bar->id);
|
"-b", bar->id, NULL};
|
||||||
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);
|
execvp(cmd[0], cmd);
|
||||||
exit(1);
|
_exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
sway_log(SWAY_DEBUG, "Spawned swaybar %d", bar->pid);
|
_exit(EXIT_SUCCESS);
|
||||||
close(filedes[0]);
|
}
|
||||||
size_t len;
|
|
||||||
if (read(filedes[1], &len, sizeof(size_t)) == sizeof(size_t)) {
|
if (close(sockets[1]) != 0) {
|
||||||
char *buf = malloc(len);
|
sway_log_errno(SWAY_ERROR, "close failed");
|
||||||
if(!buf) {
|
|
||||||
sway_log(SWAY_ERROR, "Cannot allocate error string");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (read(filedes[1], buf, len)) {
|
|
||||||
sway_log(SWAY_ERROR, "%s", buf);
|
if (waitpid(pid, NULL, 0) < 0) {
|
||||||
|
sway_log_errno(SWAY_ERROR, "waitpid failed");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
free(buf);
|
|
||||||
}
|
sway_log(SWAY_DEBUG, "Spawned swaybar %s", bar->id);
|
||||||
close(filedes[1]);
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void load_swaybar(struct bar_config *bar) {
|
void load_swaybar(struct bar_config *bar) {
|
||||||
if (bar->pid != 0) {
|
if (bar->client != NULL) {
|
||||||
terminate_swaybar(bar->pid);
|
wl_client_destroy(bar->client);
|
||||||
}
|
}
|
||||||
sway_log(SWAY_DEBUG, "Invoking swaybar for bar id '%s'", bar->id);
|
sway_log(SWAY_DEBUG, "Invoking swaybar for bar id '%s'", bar->id);
|
||||||
invoke_swaybar(bar);
|
invoke_swaybar(bar);
|
||||||
|
|
Loading…
Reference in a new issue