diff options
Diffstat (limited to 'swaybar')
-rw-r--r-- | swaybar/bar.c | 82 | ||||
-rw-r--r-- | swaybar/config.c | 1 | ||||
-rw-r--r-- | swaybar/ipc.c | 116 | ||||
-rw-r--r-- | swaybar/main.c | 10 |
4 files changed, 145 insertions, 64 deletions
diff --git a/swaybar/bar.c b/swaybar/bar.c index d80c9af3..6d2872c3 100644 --- a/swaybar/bar.c +++ b/swaybar/bar.c | |||
@@ -1,5 +1,6 @@ | |||
1 | #include <stdlib.h> | 1 | #include <stdlib.h> |
2 | #include <unistd.h> | 2 | #include <unistd.h> |
3 | #include <string.h> | ||
3 | #include <fcntl.h> | 4 | #include <fcntl.h> |
4 | #include <errno.h> | 5 | #include <errno.h> |
5 | #include <sys/types.h> | 6 | #include <sys/types.h> |
@@ -17,11 +18,7 @@ | |||
17 | static void bar_init(struct bar *bar) { | 18 | static void bar_init(struct bar *bar) { |
18 | bar->config = init_config(); | 19 | bar->config = init_config(); |
19 | bar->status = init_status_line(); | 20 | bar->status = init_status_line(); |
20 | bar->output = malloc(sizeof(struct output)); | 21 | bar->outputs = create_list(); |
21 | bar->output->window = NULL; | ||
22 | bar->output->registry = NULL; | ||
23 | bar->output->workspaces = create_list(); | ||
24 | bar->output->name = NULL; | ||
25 | } | 22 | } |
26 | 23 | ||
27 | static void spawn_status_cmd_proc(struct bar *bar) { | 24 | static void spawn_status_cmd_proc(struct bar *bar) { |
@@ -49,38 +46,50 @@ static void spawn_status_cmd_proc(struct bar *bar) { | |||
49 | } | 46 | } |
50 | } | 47 | } |
51 | 48 | ||
49 | struct output *new_output(const char *name) { | ||
50 | struct output *output = malloc(sizeof(struct output)); | ||
51 | output->name = strdup(name); | ||
52 | output->window = NULL; | ||
53 | output->registry = NULL; | ||
54 | output->workspaces = create_list(); | ||
55 | return output; | ||
56 | } | ||
52 | 57 | ||
53 | void bar_setup(struct bar *bar, const char *socket_path, const char *bar_id, int desired_output) { | 58 | void bar_setup(struct bar *bar, const char *socket_path, const char *bar_id) { |
54 | /* initialize bar with default values */ | 59 | /* initialize bar with default values */ |
55 | bar_init(bar); | 60 | bar_init(bar); |
56 | 61 | ||
57 | bar->output->registry = registry_poll(); | ||
58 | |||
59 | if (!bar->output->registry->desktop_shell) { | ||
60 | sway_abort("swaybar requires the compositor to support the desktop-shell extension."); | ||
61 | } | ||
62 | |||
63 | /* connect to sway ipc */ | 62 | /* connect to sway ipc */ |
64 | bar->ipc_socketfd = ipc_open_socket(socket_path); | 63 | bar->ipc_socketfd = ipc_open_socket(socket_path); |
65 | bar->ipc_event_socketfd = ipc_open_socket(socket_path); | 64 | bar->ipc_event_socketfd = ipc_open_socket(socket_path); |
66 | 65 | ||
67 | ipc_bar_init(bar, desired_output, bar_id); | 66 | ipc_bar_init(bar, bar_id); |
68 | 67 | ||
69 | struct output_state *output = bar->output->registry->outputs->items[desired_output]; | 68 | int i; |
69 | for (i = 0; i < bar->outputs->length; ++i) { | ||
70 | struct output *bar_output = bar->outputs->items[i]; | ||
70 | 71 | ||
71 | bar->output->window = window_setup(bar->output->registry, output->width, 30, false); | 72 | bar_output->registry = registry_poll(); |
72 | if (!bar->output->window) { | ||
73 | sway_abort("Failed to create window."); | ||
74 | } | ||
75 | desktop_shell_set_panel(bar->output->registry->desktop_shell, output->output, bar->output->window->surface); | ||
76 | desktop_shell_set_panel_position(bar->output->registry->desktop_shell, bar->config->position); | ||
77 | 73 | ||
78 | /* set font */ | 74 | if (!bar_output->registry->desktop_shell) { |
79 | bar->output->window->font = bar->config->font; | 75 | sway_abort("swaybar requires the compositor to support the desktop-shell extension."); |
76 | } | ||
80 | 77 | ||
81 | /* set window height */ | 78 | struct output_state *output = bar_output->registry->outputs->items[bar_output->idx]; |
82 | set_window_height(bar->output->window, bar->config->height); | ||
83 | 79 | ||
80 | bar_output->window = window_setup(bar_output->registry, output->width, 30, false); | ||
81 | if (!bar_output->window) { | ||
82 | sway_abort("Failed to create window."); | ||
83 | } | ||
84 | desktop_shell_set_panel(bar_output->registry->desktop_shell, output->output, bar_output->window->surface); | ||
85 | desktop_shell_set_panel_position(bar_output->registry->desktop_shell, bar->config->position); | ||
86 | |||
87 | /* set font */ | ||
88 | bar_output->window->font = bar->config->font; | ||
89 | |||
90 | /* set window height */ | ||
91 | set_window_height(bar_output->window, bar->config->height); | ||
92 | } | ||
84 | /* spawn status command */ | 93 | /* spawn status command */ |
85 | spawn_status_cmd_proc(bar); | 94 | spawn_status_cmd_proc(bar); |
86 | } | 95 | } |
@@ -92,12 +101,15 @@ void bar_run(struct bar *bar) { | |||
92 | 101 | ||
93 | while (1) { | 102 | while (1) { |
94 | if (dirty) { | 103 | if (dirty) { |
95 | struct output *output = bar->output; | 104 | int i; |
96 | if (window_prerender(output->window) && output->window->cairo) { | 105 | for (i = 0; i < bar->outputs->length; ++i) { |
97 | render(output, bar->config, bar->status); | 106 | struct output *output = bar->outputs->items[i]; |
98 | window_render(output->window); | 107 | if (window_prerender(output->window) && output->window->cairo) { |
99 | if (wl_display_dispatch(output->registry->display) == -1) { | 108 | render(output, bar->config, bar->status); |
100 | break; | 109 | window_render(output->window); |
110 | if (wl_display_dispatch(output->registry->display) == -1) { | ||
111 | break; | ||
112 | } | ||
101 | } | 113 | } |
102 | } | 114 | } |
103 | } | 115 | } |
@@ -149,6 +161,14 @@ static void free_output(struct output *output) { | |||
149 | free(output); | 161 | free(output); |
150 | } | 162 | } |
151 | 163 | ||
164 | static void free_outputs(list_t *outputs) { | ||
165 | int i; | ||
166 | for (i = 0; i < outputs->length; ++i) { | ||
167 | free_output(outputs->items[i]); | ||
168 | } | ||
169 | list_free(outputs); | ||
170 | } | ||
171 | |||
152 | static void terminate_status_command(pid_t pid) { | 172 | static void terminate_status_command(pid_t pid) { |
153 | if (pid) { | 173 | if (pid) { |
154 | // terminate status_command process | 174 | // terminate status_command process |
@@ -164,7 +184,7 @@ static void terminate_status_command(pid_t pid) { | |||
164 | 184 | ||
165 | void bar_teardown(struct bar *bar) { | 185 | void bar_teardown(struct bar *bar) { |
166 | free_config(bar->config); | 186 | free_config(bar->config); |
167 | free_output(bar->output); | 187 | free_outputs(bar->outputs); |
168 | free_status_line(bar->status); | 188 | free_status_line(bar->status); |
169 | 189 | ||
170 | /* close sockets/pipes */ | 190 | /* close sockets/pipes */ |
diff --git a/swaybar/config.c b/swaybar/config.c index 92251831..5609f85f 100644 --- a/swaybar/config.c +++ b/swaybar/config.c | |||
@@ -51,6 +51,7 @@ struct config *init_config() { | |||
51 | config->strip_workspace_numbers = false; | 51 | config->strip_workspace_numbers = false; |
52 | config->binding_mode_indicator = true; | 52 | config->binding_mode_indicator = true; |
53 | config->workspace_buttons = true; | 53 | config->workspace_buttons = true; |
54 | config->outputs = create_list(); | ||
54 | 55 | ||
55 | /* height */ | 56 | /* height */ |
56 | config->height = 0; | 57 | config->height = 0; |
diff --git a/swaybar/ipc.c b/swaybar/ipc.c index 4104103d..b5ae6747 100644 --- a/swaybar/ipc.c +++ b/swaybar/ipc.c | |||
@@ -11,7 +11,7 @@ static void ipc_parse_config(struct config *config, const char *payload) { | |||
11 | json_object *bar_config = json_tokener_parse(payload); | 11 | json_object *bar_config = json_tokener_parse(payload); |
12 | json_object *tray_output, *mode, *hidden_bar, *position, *status_command; | 12 | json_object *tray_output, *mode, *hidden_bar, *position, *status_command; |
13 | json_object *font, *bar_height, *workspace_buttons, *strip_workspace_numbers; | 13 | json_object *font, *bar_height, *workspace_buttons, *strip_workspace_numbers; |
14 | json_object *binding_mode_indicator, *verbose, *colors, *sep_symbol; | 14 | json_object *binding_mode_indicator, *verbose, *colors, *sep_symbol, *outputs; |
15 | json_object_object_get_ex(bar_config, "tray_output", &tray_output); | 15 | json_object_object_get_ex(bar_config, "tray_output", &tray_output); |
16 | json_object_object_get_ex(bar_config, "mode", &mode); | 16 | json_object_object_get_ex(bar_config, "mode", &mode); |
17 | json_object_object_get_ex(bar_config, "hidden_bar", &hidden_bar); | 17 | json_object_object_get_ex(bar_config, "hidden_bar", &hidden_bar); |
@@ -25,6 +25,7 @@ static void ipc_parse_config(struct config *config, const char *payload) { | |||
25 | json_object_object_get_ex(bar_config, "verbose", &verbose); | 25 | json_object_object_get_ex(bar_config, "verbose", &verbose); |
26 | json_object_object_get_ex(bar_config, "separator_symbol", &sep_symbol); | 26 | json_object_object_get_ex(bar_config, "separator_symbol", &sep_symbol); |
27 | json_object_object_get_ex(bar_config, "colors", &colors); | 27 | json_object_object_get_ex(bar_config, "colors", &colors); |
28 | json_object_object_get_ex(bar_config, "outputs", &outputs); | ||
28 | 29 | ||
29 | if (status_command) { | 30 | if (status_command) { |
30 | free(config->status_command); | 31 | free(config->status_command); |
@@ -61,6 +62,28 @@ static void ipc_parse_config(struct config *config, const char *payload) { | |||
61 | config->height = json_object_get_int(bar_height); | 62 | config->height = json_object_get_int(bar_height); |
62 | } | 63 | } |
63 | 64 | ||
65 | // free previous outputs list | ||
66 | int i; | ||
67 | for (i = 0; i < config->outputs->length; ++i) { | ||
68 | free(config->outputs->items[i]); | ||
69 | } | ||
70 | list_free(config->outputs); | ||
71 | config->outputs = create_list(); | ||
72 | |||
73 | if (outputs) { | ||
74 | int length = json_object_array_length(outputs); | ||
75 | json_object *output; | ||
76 | const char *output_str; | ||
77 | for (i = 0; i < length; ++i) { | ||
78 | output = json_object_array_get_idx(outputs, i); | ||
79 | output_str = json_object_get_string(output); | ||
80 | if (strcmp("*", output_str) == 0) { | ||
81 | break; | ||
82 | } | ||
83 | list_add(config->outputs, strdup(output_str)); | ||
84 | } | ||
85 | } | ||
86 | |||
64 | if (colors) { | 87 | if (colors) { |
65 | json_object *background, *statusline, *separator; | 88 | json_object *background, *statusline, *separator; |
66 | json_object *focused_workspace_border, *focused_workspace_bg, *focused_workspace_text; | 89 | json_object *focused_workspace_border, *focused_workspace_bg, *focused_workspace_text; |
@@ -151,10 +174,14 @@ static void ipc_parse_config(struct config *config, const char *payload) { | |||
151 | } | 174 | } |
152 | 175 | ||
153 | static void ipc_update_workspaces(struct bar *bar) { | 176 | static void ipc_update_workspaces(struct bar *bar) { |
154 | if (bar->output->workspaces) { | 177 | int i; |
155 | free_workspaces(bar->output->workspaces); | 178 | for (i = 0; i < bar->outputs->length; ++i) { |
179 | struct output *output = bar->outputs->items[i]; | ||
180 | if (output->workspaces) { | ||
181 | free_workspaces(output->workspaces); | ||
182 | } | ||
183 | output->workspaces = create_list(); | ||
156 | } | 184 | } |
157 | bar->output->workspaces = create_list(); | ||
158 | 185 | ||
159 | uint32_t len = 0; | 186 | uint32_t len = 0; |
160 | char *res = ipc_single_command(bar->ipc_socketfd, IPC_GET_WORKSPACES, NULL, &len); | 187 | char *res = ipc_single_command(bar->ipc_socketfd, IPC_GET_WORKSPACES, NULL, &len); |
@@ -164,7 +191,6 @@ static void ipc_update_workspaces(struct bar *bar) { | |||
164 | return; | 191 | return; |
165 | } | 192 | } |
166 | 193 | ||
167 | int i; | ||
168 | int length = json_object_array_length(results); | 194 | int length = json_object_array_length(results); |
169 | json_object *ws_json; | 195 | json_object *ws_json; |
170 | json_object *num, *name, *visible, *focused, *out, *urgent; | 196 | json_object *num, *name, *visible, *focused, *out, *urgent; |
@@ -178,14 +204,18 @@ static void ipc_update_workspaces(struct bar *bar) { | |||
178 | json_object_object_get_ex(ws_json, "output", &out); | 204 | json_object_object_get_ex(ws_json, "output", &out); |
179 | json_object_object_get_ex(ws_json, "urgent", &urgent); | 205 | json_object_object_get_ex(ws_json, "urgent", &urgent); |
180 | 206 | ||
181 | if (strcmp(json_object_get_string(out), bar->output->name) == 0) { | 207 | int j; |
182 | struct workspace *ws = malloc(sizeof(struct workspace)); | 208 | for (j = 0; j < bar->outputs->length; ++j) { |
183 | ws->num = json_object_get_int(num); | 209 | struct output *output = bar->outputs->items[j]; |
184 | ws->name = strdup(json_object_get_string(name)); | 210 | if (strcmp(json_object_get_string(out), output->name) == 0) { |
185 | ws->visible = json_object_get_boolean(visible); | 211 | struct workspace *ws = malloc(sizeof(struct workspace)); |
186 | ws->focused = json_object_get_boolean(focused); | 212 | ws->num = json_object_get_int(num); |
187 | ws->urgent = json_object_get_boolean(urgent); | 213 | ws->name = strdup(json_object_get_string(name)); |
188 | list_add(bar->output->workspaces, ws); | 214 | ws->visible = json_object_get_boolean(visible); |
215 | ws->focused = json_object_get_boolean(focused); | ||
216 | ws->urgent = json_object_get_boolean(urgent); | ||
217 | list_add(output->workspaces, ws); | ||
218 | } | ||
189 | } | 219 | } |
190 | } | 220 | } |
191 | 221 | ||
@@ -193,22 +223,58 @@ static void ipc_update_workspaces(struct bar *bar) { | |||
193 | free(res); | 223 | free(res); |
194 | } | 224 | } |
195 | 225 | ||
196 | void ipc_bar_init(struct bar *bar, int outputi, const char *bar_id) { | 226 | void ipc_bar_init(struct bar *bar, const char *bar_id) { |
197 | uint32_t len = 0; | 227 | // Get bar config |
198 | char *res = ipc_single_command(bar->ipc_socketfd, IPC_GET_OUTPUTS, NULL, &len); | 228 | uint32_t len = strlen(bar_id); |
199 | json_object *outputs = json_tokener_parse(res); | 229 | char *res = ipc_single_command(bar->ipc_socketfd, IPC_GET_BAR_CONFIG, bar_id, &len); |
200 | json_object *info = json_object_array_get_idx(outputs, outputi); | 230 | |
201 | json_object *name; | 231 | ipc_parse_config(bar->config, res); |
202 | json_object_object_get_ex(info, "name", &name); | ||
203 | bar->output->name = strdup(json_object_get_string(name)); | ||
204 | free(res); | 232 | free(res); |
205 | json_object_put(outputs); | ||
206 | 233 | ||
207 | len = strlen(bar_id); | 234 | // Get outputs |
208 | res = ipc_single_command(bar->ipc_socketfd, IPC_GET_BAR_CONFIG, bar_id, &len); | 235 | len = 0; |
236 | res = ipc_single_command(bar->ipc_socketfd, IPC_GET_OUTPUTS, NULL, &len); | ||
237 | json_object *outputs = json_tokener_parse(res); | ||
238 | int i; | ||
239 | int length = json_object_array_length(outputs); | ||
240 | json_object *output, *output_name, *output_active; | ||
241 | const char *name; | ||
242 | bool active; | ||
243 | for (i = 0; i < length; ++i) { | ||
244 | output = json_object_array_get_idx(outputs, i); | ||
245 | json_object_object_get_ex(output, "name", &output_name); | ||
246 | json_object_object_get_ex(output, "active", &output_active); | ||
247 | name = json_object_get_string(output_name); | ||
248 | active = json_object_get_boolean(output_active); | ||
249 | if (!active) { | ||
250 | continue; | ||
251 | } | ||
209 | 252 | ||
210 | ipc_parse_config(bar->config, res); | 253 | bool use_output = false; |
254 | if (bar->config->outputs->length == 0) { | ||
255 | use_output = true; | ||
256 | } else { | ||
257 | int j = 0; | ||
258 | for (j = 0; j < bar->config->outputs->length; ++j) { | ||
259 | const char *conf_name = bar->config->outputs->items[i]; | ||
260 | if (strcasecmp(name, conf_name) == 0) { | ||
261 | use_output = true; | ||
262 | break; | ||
263 | } | ||
264 | } | ||
265 | } | ||
266 | |||
267 | if (!use_output) { | ||
268 | continue; | ||
269 | } | ||
270 | |||
271 | // add bar to the output | ||
272 | struct output *bar_output = new_output(name); | ||
273 | bar_output->idx = i; | ||
274 | list_add(bar->outputs, bar_output); | ||
275 | } | ||
211 | free(res); | 276 | free(res); |
277 | json_object_put(outputs); | ||
212 | 278 | ||
213 | const char *subscribe_json = "[ \"workspace\", \"mode\" ]"; | 279 | const char *subscribe_json = "[ \"workspace\", \"mode\" ]"; |
214 | len = strlen(subscribe_json); | 280 | len = strlen(subscribe_json); |
diff --git a/swaybar/main.c b/swaybar/main.c index c6bbc7a5..d7534f5d 100644 --- a/swaybar/main.c +++ b/swaybar/main.c | |||
@@ -35,7 +35,7 @@ int main(int argc, char **argv) { | |||
35 | }; | 35 | }; |
36 | 36 | ||
37 | const char *usage = | 37 | const char *usage = |
38 | "Usage: swaybar [options...] <output>\n" | 38 | "Usage: swaybar [options...]\n" |
39 | "\n" | 39 | "\n" |
40 | " -h, --help Show help message and quit.\n" | 40 | " -h, --help Show help message and quit.\n" |
41 | " -v, --version Show the version number and quit.\n" | 41 | " -v, --version Show the version number and quit.\n" |
@@ -95,15 +95,9 @@ int main(int argc, char **argv) { | |||
95 | } | 95 | } |
96 | } | 96 | } |
97 | 97 | ||
98 | if (argc == optind) { | ||
99 | sway_abort("No output index provided"); | ||
100 | } | ||
101 | |||
102 | int desired_output = atoi(argv[optind]); | ||
103 | |||
104 | signal(SIGTERM, sig_handler); | 98 | signal(SIGTERM, sig_handler); |
105 | 99 | ||
106 | bar_setup(&swaybar, socket_path, bar_id, desired_output); | 100 | bar_setup(&swaybar, socket_path, bar_id); |
107 | 101 | ||
108 | free(socket_path); | 102 | free(socket_path); |
109 | free(bar_id); | 103 | free(bar_id); |