mirror of
https://github.com/swaywm/sway.git
synced 2026-04-28 06:46:26 -04:00
Merge 96d787fc49 into e2d49afb4a
This commit is contained in:
commit
8350cf51de
3 changed files with 80 additions and 42 deletions
|
|
@ -76,20 +76,26 @@ void free_ipc_response(struct ipc_response *response) {
|
||||||
free(response);
|
free(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
char *ipc_single_command(int socketfd, uint32_t type, const char *payload, uint32_t *len) {
|
void ipc_send_command(int socketfd, uint32_t type, const char *payload, uint32_t len) {
|
||||||
|
|
||||||
char data[ipc_header_size];
|
char data[ipc_header_size];
|
||||||
uint32_t *data32 = (uint32_t *)(data + sizeof(ipc_magic));
|
uint32_t *data32 = (uint32_t *)(data + sizeof(ipc_magic));
|
||||||
memcpy(data, ipc_magic, sizeof(ipc_magic));
|
memcpy(data, ipc_magic, sizeof(ipc_magic));
|
||||||
data32[0] = *len;
|
data32[0] = len;
|
||||||
data32[1] = type;
|
data32[1] = type;
|
||||||
|
|
||||||
if (write(socketfd, data, ipc_header_size) == -1) {
|
if (write(socketfd, data, ipc_header_size) == -1) {
|
||||||
sway_abort("Unable to send IPC header");
|
sway_abort("Unable to send IPC header");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (write(socketfd, payload, *len) == -1) {
|
if (write(socketfd, payload, len) == -1) {
|
||||||
sway_abort("Unable to send IPC payload");
|
sway_abort("Unable to send IPC payload");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
char *ipc_single_command(int socketfd, uint32_t type, const char *payload, uint32_t *len) {
|
||||||
|
|
||||||
|
ipc_send_command(socketfd, type, payload, *len);
|
||||||
|
|
||||||
struct ipc_response *resp = ipc_recv_response(socketfd);
|
struct ipc_response *resp = ipc_recv_response(socketfd);
|
||||||
char *response = resp->payload;
|
char *response = resp->payload;
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,11 @@ char *get_socketpath(void);
|
||||||
* Opens the sway socket.
|
* Opens the sway socket.
|
||||||
*/
|
*/
|
||||||
int ipc_open_socket(const char *socket_path);
|
int ipc_open_socket(const char *socket_path);
|
||||||
|
/**
|
||||||
|
* Issues a single IPC command without waiting for a response.
|
||||||
|
* Useful if events are sent on the same socket.
|
||||||
|
*/
|
||||||
|
void ipc_send_command(int socketfd, uint32_t type, const char *payload, uint32_t len);
|
||||||
/**
|
/**
|
||||||
* Issues a single IPC command and returns the buffer. len will be updated with
|
* Issues a single IPC command and returns the buffer. len will be updated with
|
||||||
* the length of the buffer returned from sway.
|
* the length of the buffer returned from sway.
|
||||||
|
|
|
||||||
103
swaybar/main.c
103
swaybar/main.c
|
|
@ -66,7 +66,7 @@ struct status_block {
|
||||||
list_t *status_line = NULL;
|
list_t *status_line = NULL;
|
||||||
|
|
||||||
list_t *workspaces = NULL;
|
list_t *workspaces = NULL;
|
||||||
int ipc_socketfd, ipc_event_socketfd;
|
int ipc_socketfd;
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
int status_read_fd;
|
int status_read_fd;
|
||||||
char line[1024];
|
char line[1024];
|
||||||
|
|
@ -158,10 +158,6 @@ void swaybar_teardown() {
|
||||||
if (ipc_socketfd) {
|
if (ipc_socketfd) {
|
||||||
close(ipc_socketfd);
|
close(ipc_socketfd);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ipc_event_socketfd) {
|
|
||||||
close(ipc_event_socketfd);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void sway_terminate(void) {
|
void sway_terminate(void) {
|
||||||
|
|
@ -193,18 +189,15 @@ void free_workspace(void *item) {
|
||||||
free(ws);
|
free(ws);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ipc_update_workspaces() {
|
void ipc_update_workspaces(char *payload) {
|
||||||
if (workspaces) {
|
if (workspaces) {
|
||||||
list_foreach(workspaces, free_workspace);
|
list_foreach(workspaces, free_workspace);
|
||||||
list_free(workspaces);
|
list_free(workspaces);
|
||||||
}
|
}
|
||||||
workspaces = create_list();
|
workspaces = create_list();
|
||||||
|
|
||||||
uint32_t len = 0;
|
json_object *results = json_tokener_parse(payload);
|
||||||
char *res = ipc_single_command(ipc_socketfd, IPC_GET_WORKSPACES, NULL, &len);
|
|
||||||
json_object *results = json_tokener_parse(res);
|
|
||||||
if (!results) {
|
if (!results) {
|
||||||
free(res);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -234,7 +227,6 @@ void ipc_update_workspaces() {
|
||||||
}
|
}
|
||||||
|
|
||||||
json_object_put(results);
|
json_object_put(results);
|
||||||
free(res);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t parse_color(const char *color) {
|
uint32_t parse_color(const char *color) {
|
||||||
|
|
@ -421,10 +413,10 @@ void bar_ipc_init(int outputi, const char *bar_id) {
|
||||||
|
|
||||||
const char *subscribe_json = "[ \"workspace\", \"mode\" ]";
|
const char *subscribe_json = "[ \"workspace\", \"mode\" ]";
|
||||||
len = strlen(subscribe_json);
|
len = strlen(subscribe_json);
|
||||||
res = ipc_single_command(ipc_event_socketfd, IPC_SUBSCRIBE, subscribe_json, &len);
|
res = ipc_single_command(ipc_socketfd, IPC_SUBSCRIBE, subscribe_json, &len);
|
||||||
free(res);
|
free(res);
|
||||||
|
|
||||||
ipc_update_workspaces();
|
ipc_send_command(ipc_socketfd, IPC_GET_WORKSPACES, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -705,7 +697,7 @@ void render() {
|
||||||
double x = 0.5;
|
double x = 0.5;
|
||||||
|
|
||||||
// Workspaces
|
// Workspaces
|
||||||
if (workspace_buttons) {
|
if (workspace_buttons && workspaces) {
|
||||||
for (i = 0; i < workspaces->length; ++i) {
|
for (i = 0; i < workspaces->length; ++i) {
|
||||||
struct workspace *ws = workspaces->items[i];
|
struct workspace *ws = workspaces->items[i];
|
||||||
render_workspace_button(ws, &x);
|
render_workspace_button(ws, &x);
|
||||||
|
|
@ -1076,10 +1068,13 @@ int i3json_handle_fd(int fd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool handle_ipc_event() {
|
bool handle_ipc_event() {
|
||||||
struct ipc_response *resp = ipc_recv_response(ipc_event_socketfd);
|
struct ipc_response *resp = ipc_recv_response(ipc_socketfd);
|
||||||
switch (resp->type) {
|
switch (resp->type) {
|
||||||
|
case IPC_GET_WORKSPACES:
|
||||||
|
ipc_update_workspaces(resp->payload);
|
||||||
|
break;
|
||||||
case IPC_EVENT_WORKSPACE:
|
case IPC_EVENT_WORKSPACE:
|
||||||
ipc_update_workspaces();
|
ipc_send_command(ipc_socketfd, IPC_GET_WORKSPACES, NULL, 0);
|
||||||
break;
|
break;
|
||||||
case IPC_EVENT_MODE: {
|
case IPC_EVENT_MODE: {
|
||||||
json_object *result = json_tokener_parse(resp->payload);
|
json_object *result = json_tokener_parse(resp->payload);
|
||||||
|
|
@ -1129,7 +1124,7 @@ void poll_for_update() {
|
||||||
|
|
||||||
dirty = false;
|
dirty = false;
|
||||||
FD_ZERO(&readfds);
|
FD_ZERO(&readfds);
|
||||||
FD_SET(ipc_event_socketfd, &readfds);
|
FD_SET(ipc_socketfd, &readfds);
|
||||||
FD_SET(status_read_fd, &readfds);
|
FD_SET(status_read_fd, &readfds);
|
||||||
|
|
||||||
activity = select(FD_SETSIZE, &readfds, NULL, NULL, NULL);
|
activity = select(FD_SETSIZE, &readfds, NULL, NULL, NULL);
|
||||||
|
|
@ -1137,7 +1132,7 @@ void poll_for_update() {
|
||||||
sway_log(L_ERROR, "polling failed: %d", errno);
|
sway_log(L_ERROR, "polling failed: %d", errno);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FD_ISSET(ipc_event_socketfd, &readfds)) {
|
if (FD_ISSET(ipc_socketfd, &readfds)) {
|
||||||
sway_log(L_DEBUG, "Got IPC event.");
|
sway_log(L_DEBUG, "Got IPC event.");
|
||||||
dirty = handle_ipc_event();
|
dirty = handle_ipc_event();
|
||||||
}
|
}
|
||||||
|
|
@ -1184,6 +1179,55 @@ void poll_for_update() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* spawn_sh_cmd forks and executes the specified shell command.
|
||||||
|
* If infd is set, it receives the fd for the shell's stdin.
|
||||||
|
* If outfd is set, it recieves the fd for the shell's stdout.
|
||||||
|
*/
|
||||||
|
int spawn_sh_cmd(char *command, int *infd, int *outfd) {
|
||||||
|
int pipeout[2];
|
||||||
|
int pipein[2];
|
||||||
|
pid_t pid;
|
||||||
|
if (infd) {
|
||||||
|
pipe(pipein);
|
||||||
|
}
|
||||||
|
if (outfd) {
|
||||||
|
pipe(pipeout);
|
||||||
|
}
|
||||||
|
pid = fork();
|
||||||
|
if (pid == 0) {
|
||||||
|
if (outfd) {
|
||||||
|
close(pipeout[0]);
|
||||||
|
dup2(pipeout[1], STDOUT_FILENO);
|
||||||
|
close(pipeout[1]);
|
||||||
|
}
|
||||||
|
if (infd) {
|
||||||
|
close(pipeout[1]);
|
||||||
|
dup2(pipeout[0], STDIN_FILENO);
|
||||||
|
close(pipeout[0]);
|
||||||
|
}
|
||||||
|
char *const cmd[] = {
|
||||||
|
"sh",
|
||||||
|
"-c",
|
||||||
|
command,
|
||||||
|
NULL,
|
||||||
|
};
|
||||||
|
execvp(cmd[0], cmd);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
close(pipeout[1]);
|
||||||
|
close(pipein[0]);
|
||||||
|
if (outfd) {
|
||||||
|
*outfd = pipeout[0];
|
||||||
|
}
|
||||||
|
if (infd) {
|
||||||
|
*infd = pipein[1];
|
||||||
|
}
|
||||||
|
return pid;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
|
|
||||||
char *socket_path = NULL;
|
char *socket_path = NULL;
|
||||||
|
|
@ -1251,7 +1295,6 @@ int main(int argc, char **argv) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ipc_socketfd = ipc_open_socket(socket_path);
|
ipc_socketfd = ipc_open_socket(socket_path);
|
||||||
ipc_event_socketfd = ipc_open_socket(socket_path);
|
|
||||||
|
|
||||||
|
|
||||||
if (argc == optind) {
|
if (argc == optind) {
|
||||||
|
|
@ -1270,28 +1313,12 @@ int main(int argc, char **argv) {
|
||||||
bar_ipc_init(desired_output, bar_id);
|
bar_ipc_init(desired_output, bar_id);
|
||||||
|
|
||||||
if (status_command) {
|
if (status_command) {
|
||||||
int pipefd[2];
|
pid = spawn_sh_cmd(status_command, NULL, &status_read_fd);
|
||||||
pipe(pipefd);
|
if (pid > 0) {
|
||||||
pid = fork();
|
|
||||||
if (pid == 0) {
|
|
||||||
close(pipefd[0]);
|
|
||||||
dup2(pipefd[1], STDOUT_FILENO);
|
|
||||||
close(pipefd[1]);
|
|
||||||
char *const cmd[] = {
|
|
||||||
"sh",
|
|
||||||
"-c",
|
|
||||||
status_command,
|
|
||||||
NULL,
|
|
||||||
};
|
|
||||||
execvp(cmd[0], cmd);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
close(pipefd[1]);
|
|
||||||
status_read_fd = pipefd[0];
|
|
||||||
fcntl(status_read_fd, F_SETFL, O_NONBLOCK);
|
fcntl(status_read_fd, F_SETFL, O_NONBLOCK);
|
||||||
line[0] = '\0';
|
line[0] = '\0';
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
signal(SIGTERM, sig_handler);
|
signal(SIGTERM, sig_handler);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue