diff options
Diffstat (limited to 'sway/config/bar.c')
-rw-r--r-- | sway/config/bar.c | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/sway/config/bar.c b/sway/config/bar.c index ecc357d0..5e02c01c 100644 --- a/sway/config/bar.c +++ b/sway/config/bar.c | |||
@@ -141,3 +141,98 @@ cleanup: | |||
141 | free_bar_config(bar); | 141 | free_bar_config(bar); |
142 | return NULL; | 142 | return NULL; |
143 | } | 143 | } |
144 | |||
145 | void invoke_swaybar(struct bar_config *bar) { | ||
146 | // Pipe to communicate errors | ||
147 | int filedes[2]; | ||
148 | if (pipe(filedes) == -1) { | ||
149 | wlr_log(L_ERROR, "Pipe setup failed! Cannot fork into bar"); | ||
150 | return; | ||
151 | } | ||
152 | |||
153 | bar->pid = fork(); | ||
154 | if (bar->pid == 0) { | ||
155 | close(filedes[0]); | ||
156 | |||
157 | // run custom swaybar | ||
158 | size_t len = snprintf(NULL, 0, "%s -b %s", | ||
159 | bar->swaybar_command ? bar->swaybar_command : "swaybar", | ||
160 | bar->id); | ||
161 | char *command = malloc(len + 1); | ||
162 | if (!command) { | ||
163 | const char msg[] = "Unable to allocate swaybar command string"; | ||
164 | size_t len = sizeof(msg); | ||
165 | if (write(filedes[1], &len, sizeof(int))) {}; | ||
166 | if (write(filedes[1], msg, len)) {}; | ||
167 | close(filedes[1]); | ||
168 | exit(1); | ||
169 | } | ||
170 | snprintf(command, len + 1, "%s -b %s", | ||
171 | bar->swaybar_command ? bar->swaybar_command : "swaybar", | ||
172 | bar->id); | ||
173 | char *const cmd[] = { "sh", "-c", command, NULL, }; | ||
174 | close(filedes[1]); | ||
175 | execvp(cmd[0], cmd); | ||
176 | exit(1); | ||
177 | } | ||
178 | close(filedes[0]); | ||
179 | ssize_t len; | ||
180 | if (read(filedes[1], &len, sizeof(int)) == sizeof(int)) { | ||
181 | char *buf = malloc(len); | ||
182 | if(!buf) { | ||
183 | wlr_log(L_ERROR, "Cannot allocate error string"); | ||
184 | return; | ||
185 | } | ||
186 | if (read(filedes[1], buf, len)) { | ||
187 | wlr_log(L_ERROR, "%s", buf); | ||
188 | } | ||
189 | free(buf); | ||
190 | } | ||
191 | close(filedes[1]); | ||
192 | } | ||
193 | |||
194 | static void terminate_swaybar(pid_t pid) { | ||
195 | int ret = kill(pid, SIGTERM); | ||
196 | if (ret != 0) { | ||
197 | wlr_log_errno(L_ERROR, "Unable to terminate swaybar %d", pid); | ||
198 | } else { | ||
199 | int status; | ||
200 | waitpid(pid, &status, 0); | ||
201 | } | ||
202 | } | ||
203 | |||
204 | static bool active_output(const char *name) { | ||
205 | swayc_t *cont = NULL; | ||
206 | for (int i = 0; i < root_container.children->length; ++i) { | ||
207 | cont = root_container.children->items[i]; | ||
208 | if (cont->type == C_OUTPUT && strcasecmp(name, cont->name) == 0) { | ||
209 | return true; | ||
210 | } | ||
211 | } | ||
212 | return false; | ||
213 | } | ||
214 | |||
215 | void load_swaybars() { | ||
216 | for (int i = 0; i < config->bars->length; ++i) { | ||
217 | struct bar_config *bar = config->bars->items[i]; | ||
218 | bool apply = false; | ||
219 | if (bar->outputs) { | ||
220 | for (int j = 0; j < bar->outputs->length; ++j) { | ||
221 | char *o = bar->outputs->items[j]; | ||
222 | if (!strcmp(o, "*") || active_output(o)) { | ||
223 | apply = true; | ||
224 | break; | ||
225 | } | ||
226 | } | ||
227 | } else { | ||
228 | apply = true; | ||
229 | } | ||
230 | if (apply) { | ||
231 | if (bar->pid != 0) { | ||
232 | terminate_swaybar(bar->pid); | ||
233 | } | ||
234 | wlr_log(L_DEBUG, "Invoking swaybar for bar id '%s'", bar->id); | ||
235 | invoke_swaybar(bar); | ||
236 | } | ||
237 | } | ||
238 | } | ||