aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--common/ipc-client.c31
-rw-r--r--include/ipc-client.h5
-rw-r--r--swaybar/main.c140
3 files changed, 103 insertions, 73 deletions
diff --git a/common/ipc-client.c b/common/ipc-client.c
index 5d2d5808..e92a09fe 100644
--- a/common/ipc-client.c
+++ b/common/ipc-client.c
@@ -39,20 +39,9 @@ int ipc_open_socket(const char *socket_path) {
39 return socketfd; 39 return socketfd;
40} 40}
41 41
42char *ipc_single_command(int socketfd, uint32_t type, const char *payload, uint32_t *len) { 42char *ipc_recv_response(int socketfd, uint32_t *len) {
43 char data[ipc_header_size]; 43 char data[ipc_header_size];
44 uint32_t *data32 = (uint32_t *)(data + sizeof(ipc_magic)); 44 uint32_t *data32 = (uint32_t *)(data + sizeof(ipc_magic));
45 memcpy(data, ipc_magic, sizeof(ipc_magic));
46 data32[0] = *len;
47 data32[1] = type;
48
49 if (write(socketfd, data, ipc_header_size) == -1) {
50 sway_abort("Unable to send IPC header");
51 }
52
53 if (write(socketfd, payload, *len) == -1) {
54 sway_abort("Unable to send IPC payload");
55 }
56 45
57 size_t total = 0; 46 size_t total = 0;
58 while (total < ipc_header_size) { 47 while (total < ipc_header_size) {
@@ -77,3 +66,21 @@ char *ipc_single_command(int socketfd, uint32_t type, const char *payload, uint3
77 66
78 return response; 67 return response;
79} 68}
69
70char *ipc_single_command(int socketfd, uint32_t type, const char *payload, uint32_t *len) {
71 char data[ipc_header_size];
72 uint32_t *data32 = (uint32_t *)(data + sizeof(ipc_magic));
73 memcpy(data, ipc_magic, sizeof(ipc_magic));
74 data32[0] = *len;
75 data32[1] = type;
76
77 if (write(socketfd, data, ipc_header_size) == -1) {
78 sway_abort("Unable to send IPC header");
79 }
80
81 if (write(socketfd, payload, *len) == -1) {
82 sway_abort("Unable to send IPC payload");
83 }
84
85 return ipc_recv_response(socketfd, len);
86}
diff --git a/include/ipc-client.h b/include/ipc-client.h
index e6c988c2..a4cfd87f 100644
--- a/include/ipc-client.h
+++ b/include/ipc-client.h
@@ -16,5 +16,10 @@ int ipc_open_socket(const char *socket_path);
16 * the length of the buffer returned from sway. 16 * the length of the buffer returned from sway.
17 */ 17 */
18char *ipc_single_command(int socketfd, uint32_t type, const char *payload, uint32_t *len); 18char *ipc_single_command(int socketfd, uint32_t type, const char *payload, uint32_t *len);
19/**
20 * Receives a single IPC resposne and returns the buffer. len will be updated
21 * with the length of the buffer returned from sway.
22 */
23char *ipc_recv_response(int socketfd, uint32_t *len);
19 24
20#endif 25#endif
diff --git a/swaybar/main.c b/swaybar/main.c
index c7c4ed47..56c69aff 100644
--- a/swaybar/main.c
+++ b/swaybar/main.c
@@ -3,7 +3,11 @@
3#include <string.h> 3#include <string.h>
4#include <stdint.h> 4#include <stdint.h>
5#include <stdbool.h> 5#include <stdbool.h>
6#include <stropts.h>
6#include <json-c/json.h> 7#include <json-c/json.h>
8#include <sys/un.h>
9#include <sys/socket.h>
10#include <sys/ioctl.h>
7#include "ipc-client.h" 11#include "ipc-client.h"
8#include "readline.h" 12#include "readline.h"
9#include "client/registry.h" 13#include "client/registry.h"
@@ -93,8 +97,74 @@ void cairo_set_source_u32(cairo_t *cairo, uint32_t color) {
93 (color & 0xFF) / 256.0); 97 (color & 0xFF) / 256.0);
94} 98}
95 99
100void ipc_update_workspaces() {
101 if (workspaces) {
102 free_flat_list(workspaces);
103 }
104 workspaces = create_list();
105
106 uint32_t len = 0;
107 char *res = ipc_single_command(socketfd, IPC_GET_WORKSPACES, NULL, &len);
108 json_object *results = json_tokener_parse(res);
109
110 int i;
111 for (i = 0; i < json_object_array_length(results); ++i) {
112 json_object *ws_json = json_object_array_get_idx(results, i);
113 json_object *num, *name, *visible, *focused, *out, *urgent;
114 json_object_object_get_ex(ws_json, "num", &num);
115 json_object_object_get_ex(ws_json, "name", &name);
116 json_object_object_get_ex(ws_json, "visible", &visible);
117 json_object_object_get_ex(ws_json, "focused", &focused);
118 json_object_object_get_ex(ws_json, "output", &out);
119 json_object_object_get_ex(ws_json, "urgent", &urgent);
120
121 if (strcmp(json_object_get_string(out), output) == 0) {
122 struct workspace *ws = malloc(sizeof(struct workspace));
123 ws->num = json_object_get_int(num);
124 ws->name = strdup(json_object_get_string(name));
125 ws->visible = json_object_get_boolean(visible);
126 ws->focused = json_object_get_boolean(focused);
127 ws->urgent = json_object_get_boolean(urgent);
128 list_add(workspaces, ws);
129 sway_log(L_INFO, "Handling workspace %s", ws->name);
130 }
131
132 json_object_put(num);
133 json_object_put(name);
134 json_object_put(visible);
135 json_object_put(focused);
136 json_object_put(out);
137 json_object_put(urgent);
138 json_object_put(ws_json);
139 }
140
141 json_object_put(results);
142 free(res);
143}
144
145void bar_ipc_init(int outputi) {
146 uint32_t len = 0;
147 char *res = ipc_single_command(socketfd, IPC_GET_OUTPUTS, NULL, &len);
148 json_object *outputs = json_tokener_parse(res);
149 json_object *info = json_object_array_get_idx(outputs, outputi);
150 json_object *name;
151 json_object_object_get_ex(info, "name", &name);
152 output = strdup(json_object_get_string(name));
153 free(res);
154 json_object_put(outputs);
155 sway_log(L_INFO, "Running on output %s", output);
156
157 const char *subscribe_json = "[ \"workspace\" ]";
158 len = strlen(subscribe_json);
159 res = ipc_single_command(socketfd, IPC_SUBSCRIBE, subscribe_json, &len);
160 sway_log(L_INFO, "%s", res);
161
162 ipc_update_workspaces();
163}
164
96void update() { 165void update() {
97 if (!feof(command)) { 166 int pending;
167 if (ioctl(fileno(command), FIONREAD, &pending) != -1 && pending > 0) {
98 free(line); 168 free(line);
99 line = read_line(command); 169 line = read_line(command);
100 int l = strlen(line) - 1; 170 int l = strlen(line) - 1;
@@ -102,6 +172,14 @@ void update() {
102 line[l] = '\0'; 172 line[l] = '\0';
103 } 173 }
104 } 174 }
175 if (ioctl(socketfd, FIONREAD, &pending) != -1 && pending > 0) {
176 sway_log(L_INFO, "data available");
177 uint32_t len;
178 char *buf = ipc_recv_response(socketfd, &len);
179 sway_log(L_INFO, "%s", buf);
180 free(buf);
181 ipc_update_workspaces();
182 }
105} 183}
106 184
107void render() { 185void render() {
@@ -155,66 +233,6 @@ void render() {
155 } 233 }
156} 234}
157 235
158void ipc_update_workspaces() {
159 if (workspaces) {
160 free_flat_list(workspaces);
161 }
162 workspaces = create_list();
163
164 uint32_t len = 0;
165 char *res = ipc_single_command(socketfd, IPC_GET_WORKSPACES, NULL, &len);
166 json_object *results = json_tokener_parse(res);
167
168 int i;
169 for (i = 0; i < json_object_array_length(results); ++i) {
170 json_object *ws_json = json_object_array_get_idx(results, i);
171 json_object *num, *name, *visible, *focused, *out, *urgent;
172 json_object_object_get_ex(ws_json, "num", &num);
173 json_object_object_get_ex(ws_json, "name", &name);
174 json_object_object_get_ex(ws_json, "visible", &visible);
175 json_object_object_get_ex(ws_json, "focused", &focused);
176 json_object_object_get_ex(ws_json, "output", &out);
177 json_object_object_get_ex(ws_json, "urgent", &urgent);
178
179 if (strcmp(json_object_get_string(out), output) == 0) {
180 struct workspace *ws = malloc(sizeof(struct workspace));
181 ws->num = json_object_get_int(num);
182 ws->name = strdup(json_object_get_string(name));
183 ws->visible = json_object_get_boolean(visible);
184 ws->focused = json_object_get_boolean(focused);
185 ws->urgent = json_object_get_boolean(urgent);
186 list_add(workspaces, ws);
187 sway_log(L_INFO, "Handling workspace %s", ws->name);
188 }
189
190 json_object_put(num);
191 json_object_put(name);
192 json_object_put(visible);
193 json_object_put(focused);
194 json_object_put(out);
195 json_object_put(urgent);
196 json_object_put(ws_json);
197 }
198
199 json_object_put(results);
200 free(res);
201}
202
203void bar_ipc_init(int outputi) {
204 uint32_t len = 0;
205 char *res = ipc_single_command(socketfd, IPC_GET_OUTPUTS, NULL, &len);
206 json_object *outputs = json_tokener_parse(res);
207 json_object *info = json_object_array_get_idx(outputs, outputi);
208 json_object *name;
209 json_object_object_get_ex(info, "name", &name);
210 output = strdup(json_object_get_string(name));
211 free(res);
212 json_object_put(outputs);
213 sway_log(L_INFO, "Running on output %s", output);
214
215 ipc_update_workspaces();
216}
217
218int main(int argc, char **argv) { 236int main(int argc, char **argv) {
219 init_log(L_INFO); 237 init_log(L_INFO);
220 registry = registry_poll(); 238 registry = registry_poll();