diff options
-rw-r--r-- | include/bar/bar.h | 11 | ||||
-rw-r--r-- | include/bar/config.h | 3 | ||||
-rw-r--r-- | include/bar/ipc.h | 2 | ||||
-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 |
7 files changed, 157 insertions, 68 deletions
diff --git a/include/bar/bar.h b/include/bar/bar.h index 89496da6..c20efc55 100644 --- a/include/bar/bar.h +++ b/include/bar/bar.h | |||
@@ -8,8 +8,7 @@ | |||
8 | struct bar { | 8 | struct bar { |
9 | struct config *config; | 9 | struct config *config; |
10 | struct status_line *status; | 10 | struct status_line *status; |
11 | struct output *output; | 11 | list_t *outputs; |
12 | /* list_t *outputs; */ | ||
13 | 12 | ||
14 | int ipc_event_socketfd; | 13 | int ipc_event_socketfd; |
15 | int ipc_socketfd; | 14 | int ipc_socketfd; |
@@ -22,6 +21,7 @@ struct output { | |||
22 | struct registry *registry; | 21 | struct registry *registry; |
23 | list_t *workspaces; | 22 | list_t *workspaces; |
24 | char *name; | 23 | char *name; |
24 | int idx; | ||
25 | }; | 25 | }; |
26 | 26 | ||
27 | struct workspace { | 27 | struct workspace { |
@@ -35,7 +35,12 @@ struct workspace { | |||
35 | /** | 35 | /** |
36 | * Setup bar. | 36 | * Setup bar. |
37 | */ | 37 | */ |
38 | void bar_setup(struct bar *bar, const char *socket_path, const char *bar_id, int desired_output); | 38 | void bar_setup(struct bar *bar, const char *socket_path, const char *bar_id); |
39 | |||
40 | /** | ||
41 | * Create new output struct from name. | ||
42 | */ | ||
43 | struct output *new_output(const char *name); | ||
39 | 44 | ||
40 | /** | 45 | /** |
41 | * Bar mainloop. | 46 | * Bar mainloop. |
diff --git a/include/bar/config.h b/include/bar/config.h index 508b9c42..dfad0ba4 100644 --- a/include/bar/config.h +++ b/include/bar/config.h | |||
@@ -4,6 +4,8 @@ | |||
4 | #include <stdint.h> | 4 | #include <stdint.h> |
5 | #include <stdbool.h> | 5 | #include <stdbool.h> |
6 | 6 | ||
7 | #include "list.h" | ||
8 | |||
7 | /** | 9 | /** |
8 | * Colors for a box with background, border and text colors. | 10 | * Colors for a box with background, border and text colors. |
9 | */ | 11 | */ |
@@ -25,6 +27,7 @@ struct config { | |||
25 | bool strip_workspace_numbers; | 27 | bool strip_workspace_numbers; |
26 | bool binding_mode_indicator; | 28 | bool binding_mode_indicator; |
27 | bool workspace_buttons; | 29 | bool workspace_buttons; |
30 | list_t *outputs; | ||
28 | 31 | ||
29 | int height; | 32 | int height; |
30 | 33 | ||
diff --git a/include/bar/ipc.h b/include/bar/ipc.h index c3f661f8..741c067b 100644 --- a/include/bar/ipc.h +++ b/include/bar/ipc.h | |||
@@ -6,7 +6,7 @@ | |||
6 | /** | 6 | /** |
7 | * Initialize ipc connection to sway and get sway state, outputs, bar_config. | 7 | * Initialize ipc connection to sway and get sway state, outputs, bar_config. |
8 | */ | 8 | */ |
9 | void ipc_bar_init(struct bar *bar, int outputi, const char *bar_id); | 9 | void ipc_bar_init(struct bar *bar, const char *bar_id); |
10 | 10 | ||
11 | /** | 11 | /** |
12 | * Handle ipc event from sway. | 12 | * Handle ipc event from sway. |
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); |