diff options
Diffstat (limited to 'swaybar/main.c')
-rw-r--r-- | swaybar/main.c | 255 |
1 files changed, 10 insertions, 245 deletions
diff --git a/swaybar/main.c b/swaybar/main.c index 6ba7c825..a521fa79 100644 --- a/swaybar/main.c +++ b/swaybar/main.c | |||
@@ -23,8 +23,8 @@ | |||
23 | #include "config.h" | 23 | #include "config.h" |
24 | #include "render.h" | 24 | #include "render.h" |
25 | #include "status_line.h" | 25 | #include "status_line.h" |
26 | #include "ipc.h" | ||
26 | 27 | ||
27 | char *output; | ||
28 | struct swaybar_state *state; | 28 | struct swaybar_state *state; |
29 | 29 | ||
30 | void swaybar_teardown() { | 30 | void swaybar_teardown() { |
@@ -71,247 +71,6 @@ void sig_handler(int signal) { | |||
71 | exit(0); | 71 | exit(0); |
72 | } | 72 | } |
73 | 73 | ||
74 | void ipc_update_workspaces() { | ||
75 | if (state->output->workspaces) { | ||
76 | list_foreach(state->output->workspaces, free_workspace); | ||
77 | list_free(state->output->workspaces); | ||
78 | } | ||
79 | state->output->workspaces = create_list(); | ||
80 | |||
81 | uint32_t len = 0; | ||
82 | char *res = ipc_single_command(state->ipc_socketfd, IPC_GET_WORKSPACES, NULL, &len); | ||
83 | json_object *results = json_tokener_parse(res); | ||
84 | if (!results) { | ||
85 | free(res); | ||
86 | return; | ||
87 | } | ||
88 | |||
89 | int i; | ||
90 | int length = json_object_array_length(results); | ||
91 | json_object *ws_json; | ||
92 | json_object *num, *name, *visible, *focused, *out, *urgent; | ||
93 | for (i = 0; i < length; ++i) { | ||
94 | ws_json = json_object_array_get_idx(results, i); | ||
95 | |||
96 | json_object_object_get_ex(ws_json, "num", &num); | ||
97 | json_object_object_get_ex(ws_json, "name", &name); | ||
98 | json_object_object_get_ex(ws_json, "visible", &visible); | ||
99 | json_object_object_get_ex(ws_json, "focused", &focused); | ||
100 | json_object_object_get_ex(ws_json, "output", &out); | ||
101 | json_object_object_get_ex(ws_json, "urgent", &urgent); | ||
102 | |||
103 | if (strcmp(json_object_get_string(out), output) == 0) { | ||
104 | struct workspace *ws = malloc(sizeof(struct workspace)); | ||
105 | ws->num = json_object_get_int(num); | ||
106 | ws->name = strdup(json_object_get_string(name)); | ||
107 | ws->visible = json_object_get_boolean(visible); | ||
108 | ws->focused = json_object_get_boolean(focused); | ||
109 | ws->urgent = json_object_get_boolean(urgent); | ||
110 | list_add(state->output->workspaces, ws); | ||
111 | } | ||
112 | } | ||
113 | |||
114 | json_object_put(results); | ||
115 | free(res); | ||
116 | } | ||
117 | |||
118 | void bar_ipc_init(int outputi, const char *bar_id) { | ||
119 | uint32_t len = 0; | ||
120 | char *res = ipc_single_command(state->ipc_socketfd, IPC_GET_OUTPUTS, NULL, &len); | ||
121 | json_object *outputs = json_tokener_parse(res); | ||
122 | json_object *info = json_object_array_get_idx(outputs, outputi); | ||
123 | json_object *name; | ||
124 | json_object_object_get_ex(info, "name", &name); | ||
125 | output = strdup(json_object_get_string(name)); | ||
126 | free(res); | ||
127 | json_object_put(outputs); | ||
128 | |||
129 | len = strlen(bar_id); | ||
130 | res = ipc_single_command(state->ipc_socketfd, IPC_GET_BAR_CONFIG, bar_id, &len); | ||
131 | |||
132 | json_object *bar_config = json_tokener_parse(res); | ||
133 | json_object *tray_output, *mode, *hidden_state, *position, *_status_command; | ||
134 | json_object *font, *bar_height, *_workspace_buttons, *_strip_workspace_numbers; | ||
135 | json_object *_binding_mode_indicator, *verbose, *_colors, *sep_symbol; | ||
136 | json_object_object_get_ex(bar_config, "tray_output", &tray_output); | ||
137 | json_object_object_get_ex(bar_config, "mode", &mode); | ||
138 | json_object_object_get_ex(bar_config, "hidden_state", &hidden_state); | ||
139 | json_object_object_get_ex(bar_config, "position", &position); | ||
140 | json_object_object_get_ex(bar_config, "status_command", &_status_command); | ||
141 | json_object_object_get_ex(bar_config, "font", &font); | ||
142 | json_object_object_get_ex(bar_config, "bar_height", &bar_height); | ||
143 | json_object_object_get_ex(bar_config, "workspace_buttons", &_workspace_buttons); | ||
144 | json_object_object_get_ex(bar_config, "strip_workspace_numbers", &_strip_workspace_numbers); | ||
145 | json_object_object_get_ex(bar_config, "binding_mode_indicator", &_binding_mode_indicator); | ||
146 | json_object_object_get_ex(bar_config, "verbose", &verbose); | ||
147 | json_object_object_get_ex(bar_config, "separator_symbol", &sep_symbol); | ||
148 | json_object_object_get_ex(bar_config, "colors", &_colors); | ||
149 | |||
150 | // TODO: More of these options | ||
151 | // TODO: Refactor swaybar into several files, create a bar config struct (shared with compositor?) | ||
152 | if (_status_command) { | ||
153 | free(state->config->status_command); | ||
154 | state->config->status_command = strdup(json_object_get_string(_status_command)); | ||
155 | } | ||
156 | |||
157 | if (position) { | ||
158 | state->config->position = parse_position(json_object_get_string(position)); | ||
159 | desktop_shell_set_panel_position(state->output->registry->desktop_shell, state->config->position); | ||
160 | } | ||
161 | |||
162 | if (font) { | ||
163 | state->output->window->font = parse_font(json_object_get_string(font)); | ||
164 | } | ||
165 | |||
166 | if (sep_symbol) { | ||
167 | free(state->config->sep_symbol); | ||
168 | state->config->sep_symbol = strdup(json_object_get_string(sep_symbol)); | ||
169 | } | ||
170 | |||
171 | if (_strip_workspace_numbers) { | ||
172 | state->config->strip_workspace_numbers = json_object_get_boolean(_strip_workspace_numbers); | ||
173 | } | ||
174 | |||
175 | if (_binding_mode_indicator) { | ||
176 | state->config->binding_mode_indicator = json_object_get_boolean(_binding_mode_indicator); | ||
177 | } | ||
178 | |||
179 | if (_workspace_buttons) { | ||
180 | state->config->workspace_buttons = json_object_get_boolean(_workspace_buttons); | ||
181 | } | ||
182 | |||
183 | if (bar_height) { | ||
184 | int width, height; | ||
185 | get_text_size(state->output->window, &width, &height, "Test string for measuring purposes"); | ||
186 | int bar_height_value = json_object_get_int(bar_height); | ||
187 | if (bar_height_value > 0) { | ||
188 | state->config->margin = (bar_height_value - height) / 2; | ||
189 | state->config->ws_vertical_padding = state->config->margin - 1.5; | ||
190 | } | ||
191 | state->output->window->height = height + state->config->margin * 2; | ||
192 | } | ||
193 | |||
194 | if (_colors) { | ||
195 | json_object *background, *statusline, *separator; | ||
196 | json_object *focused_workspace_border, *focused_workspace_bg, *focused_workspace_text; | ||
197 | json_object *inactive_workspace_border, *inactive_workspace_bg, *inactive_workspace_text; | ||
198 | json_object *active_workspace_border, *active_workspace_bg, *active_workspace_text; | ||
199 | json_object *urgent_workspace_border, *urgent_workspace_bg, *urgent_workspace_text; | ||
200 | json_object *binding_mode_border, *binding_mode_bg, *binding_mode_text; | ||
201 | json_object_object_get_ex(_colors, "background", &background); | ||
202 | json_object_object_get_ex(_colors, "statusline", &statusline); | ||
203 | json_object_object_get_ex(_colors, "separator", &separator); | ||
204 | json_object_object_get_ex(_colors, "focused_workspace_border", &focused_workspace_border); | ||
205 | json_object_object_get_ex(_colors, "focused_workspace_bg", &focused_workspace_bg); | ||
206 | json_object_object_get_ex(_colors, "focused_workspace_text", &focused_workspace_text); | ||
207 | json_object_object_get_ex(_colors, "active_workspace_border", &active_workspace_border); | ||
208 | json_object_object_get_ex(_colors, "active_workspace_bg", &active_workspace_bg); | ||
209 | json_object_object_get_ex(_colors, "active_workspace_text", &active_workspace_text); | ||
210 | json_object_object_get_ex(_colors, "inactive_workspace_border", &inactive_workspace_border); | ||
211 | json_object_object_get_ex(_colors, "inactive_workspace_bg", &inactive_workspace_bg); | ||
212 | json_object_object_get_ex(_colors, "inactive_workspace_text", &inactive_workspace_text); | ||
213 | json_object_object_get_ex(_colors, "urgent_workspace_border", &urgent_workspace_border); | ||
214 | json_object_object_get_ex(_colors, "urgent_workspace_bg", &urgent_workspace_bg); | ||
215 | json_object_object_get_ex(_colors, "urgent_workspace_text", &urgent_workspace_text); | ||
216 | json_object_object_get_ex(_colors, "binding_mode_border", &binding_mode_border); | ||
217 | json_object_object_get_ex(_colors, "binding_mode_bg", &binding_mode_bg); | ||
218 | json_object_object_get_ex(_colors, "binding_mode_text", &binding_mode_text); | ||
219 | if (background) { | ||
220 | state->config->colors.background = parse_color(json_object_get_string(background)); | ||
221 | } | ||
222 | if (statusline) { | ||
223 | state->config->colors.statusline = parse_color(json_object_get_string(statusline)); | ||
224 | } | ||
225 | if (separator) { | ||
226 | state->config->colors.separator = parse_color(json_object_get_string(separator)); | ||
227 | } | ||
228 | if (focused_workspace_border) { | ||
229 | state->config->colors.focused_workspace.border = parse_color(json_object_get_string(focused_workspace_border)); | ||
230 | } | ||
231 | if (focused_workspace_bg) { | ||
232 | state->config->colors.focused_workspace.background = parse_color(json_object_get_string(focused_workspace_bg)); | ||
233 | } | ||
234 | if (focused_workspace_text) { | ||
235 | state->config->colors.focused_workspace.text = parse_color(json_object_get_string(focused_workspace_text)); | ||
236 | } | ||
237 | if (active_workspace_border) { | ||
238 | state->config->colors.active_workspace.border = parse_color(json_object_get_string(active_workspace_border)); | ||
239 | } | ||
240 | if (active_workspace_bg) { | ||
241 | state->config->colors.active_workspace.background = parse_color(json_object_get_string(active_workspace_bg)); | ||
242 | } | ||
243 | if (active_workspace_text) { | ||
244 | state->config->colors.active_workspace.text = parse_color(json_object_get_string(active_workspace_text)); | ||
245 | } | ||
246 | if (inactive_workspace_border) { | ||
247 | state->config->colors.inactive_workspace.border = parse_color(json_object_get_string(inactive_workspace_border)); | ||
248 | } | ||
249 | if (inactive_workspace_bg) { | ||
250 | state->config->colors.inactive_workspace.background = parse_color(json_object_get_string(inactive_workspace_bg)); | ||
251 | } | ||
252 | if (inactive_workspace_text) { | ||
253 | state->config->colors.inactive_workspace.text = parse_color(json_object_get_string(inactive_workspace_text)); | ||
254 | } | ||
255 | if (binding_mode_border) { | ||
256 | state->config->colors.binding_mode.border = parse_color(json_object_get_string(binding_mode_border)); | ||
257 | } | ||
258 | if (binding_mode_bg) { | ||
259 | state->config->colors.binding_mode.background = parse_color(json_object_get_string(binding_mode_bg)); | ||
260 | } | ||
261 | if (binding_mode_text) { | ||
262 | state->config->colors.binding_mode.text = parse_color(json_object_get_string(binding_mode_text)); | ||
263 | } | ||
264 | } | ||
265 | |||
266 | json_object_put(bar_config); | ||
267 | free(res); | ||
268 | |||
269 | const char *subscribe_json = "[ \"workspace\", \"mode\" ]"; | ||
270 | len = strlen(subscribe_json); | ||
271 | res = ipc_single_command(state->ipc_event_socketfd, IPC_SUBSCRIBE, subscribe_json, &len); | ||
272 | free(res); | ||
273 | |||
274 | ipc_update_workspaces(); | ||
275 | } | ||
276 | bool handle_ipc_event() { | ||
277 | struct ipc_response *resp = ipc_recv_response(state->ipc_event_socketfd); | ||
278 | switch (resp->type) { | ||
279 | case IPC_EVENT_WORKSPACE: | ||
280 | ipc_update_workspaces(); | ||
281 | break; | ||
282 | case IPC_EVENT_MODE: { | ||
283 | json_object *result = json_tokener_parse(resp->payload); | ||
284 | if (!result) { | ||
285 | free_ipc_response(resp); | ||
286 | sway_log(L_ERROR, "failed to parse payload as json"); | ||
287 | return false; | ||
288 | } | ||
289 | json_object *json_change; | ||
290 | if (json_object_object_get_ex(result, "change", &json_change)) { | ||
291 | const char *change = json_object_get_string(json_change); | ||
292 | |||
293 | free(state->config->mode); | ||
294 | if (strcmp(change, "default") == 0) { | ||
295 | state->config->mode = NULL; | ||
296 | } else { | ||
297 | state->config->mode = strdup(change); | ||
298 | } | ||
299 | } else { | ||
300 | sway_log(L_ERROR, "failed to parse response"); | ||
301 | } | ||
302 | |||
303 | json_object_put(result); | ||
304 | break; | ||
305 | } | ||
306 | default: | ||
307 | free_ipc_response(resp); | ||
308 | return false; | ||
309 | } | ||
310 | |||
311 | free_ipc_response(resp); | ||
312 | return true; | ||
313 | } | ||
314 | |||
315 | void poll_for_update() { | 74 | void poll_for_update() { |
316 | fd_set readfds; | 75 | fd_set readfds; |
317 | int activity; | 76 | int activity; |
@@ -341,7 +100,7 @@ void poll_for_update() { | |||
341 | 100 | ||
342 | if (FD_ISSET(state->ipc_event_socketfd, &readfds)) { | 101 | if (FD_ISSET(state->ipc_event_socketfd, &readfds)) { |
343 | sway_log(L_DEBUG, "Got IPC event."); | 102 | sway_log(L_DEBUG, "Got IPC event."); |
344 | dirty = handle_ipc_event(); | 103 | dirty = handle_ipc_event(state); |
345 | } | 104 | } |
346 | 105 | ||
347 | if (state->config->status_command && FD_ISSET(state->status_read_fd, &readfds)) { | 106 | if (state->config->status_command && FD_ISSET(state->status_read_fd, &readfds)) { |
@@ -435,12 +194,13 @@ int main(int argc, char **argv) { | |||
435 | state->ipc_socketfd = ipc_open_socket(socket_path); | 194 | state->ipc_socketfd = ipc_open_socket(socket_path); |
436 | state->ipc_event_socketfd = ipc_open_socket(socket_path); | 195 | state->ipc_event_socketfd = ipc_open_socket(socket_path); |
437 | 196 | ||
438 | |||
439 | if (argc == optind) { | 197 | if (argc == optind) { |
440 | sway_abort("No output index provided"); | 198 | sway_abort("No output index provided"); |
441 | } | 199 | } |
442 | 200 | ||
443 | int desired_output = atoi(argv[optind]); | 201 | int desired_output = atoi(argv[optind]); |
202 | ipc_bar_init(state, desired_output, bar_id); | ||
203 | |||
444 | struct output_state *output = state->output->registry->outputs->items[desired_output]; | 204 | struct output_state *output = state->output->registry->outputs->items[desired_output]; |
445 | 205 | ||
446 | state->output->window = window_setup(state->output->registry, output->width, 30, false); | 206 | state->output->window = window_setup(state->output->registry, output->width, 30, false); |
@@ -448,8 +208,13 @@ int main(int argc, char **argv) { | |||
448 | sway_abort("Failed to create window."); | 208 | sway_abort("Failed to create window."); |
449 | } | 209 | } |
450 | desktop_shell_set_panel(state->output->registry->desktop_shell, output->output, state->output->window->surface); | 210 | desktop_shell_set_panel(state->output->registry->desktop_shell, output->output, state->output->window->surface); |
211 | desktop_shell_set_panel_position(state->output->registry->desktop_shell, state->config->position); | ||
212 | |||
213 | /* set font */ | ||
214 | state->output->window->font = state->config->font; | ||
451 | 215 | ||
452 | bar_ipc_init(desired_output, bar_id); | 216 | /* set window height */ |
217 | set_window_height(state->output->window, state->config->height); | ||
453 | 218 | ||
454 | if (state->config->status_command) { | 219 | if (state->config->status_command) { |
455 | int pipefd[2]; | 220 | int pipefd[2]; |