summaryrefslogtreecommitdiffstats
path: root/swaybar/main.c
diff options
context:
space:
mode:
authorLibravatar Mikkel Oscar Lyderik <mikkeloscar@gmail.com>2015-12-19 16:24:51 +0100
committerLibravatar Mikkel Oscar Lyderik <mikkeloscar@gmail.com>2015-12-19 16:33:58 +0100
commitbc9b93f597fed421739e4d36379c288084504971 (patch)
treeaf201185678cc8bc5441181ea88d08694d020f8e /swaybar/main.c
parentMerge pull request #364 from cyberhuman/master (diff)
downloadsway-bc9b93f597fed421739e4d36379c288084504971.tar.gz
sway-bc9b93f597fed421739e4d36379c288084504971.tar.zst
sway-bc9b93f597fed421739e4d36379c288084504971.zip
swaybar: use select instead of busyloop
Use of busyloop caused high cpu usage for sway because swaybar had to be redrawn all the time. By using select instead the bar only has to be redrawn when the status_command changes (i.e. every second) or when the workspaces are updated. Fix #345
Diffstat (limited to 'swaybar/main.c')
-rw-r--r--swaybar/main.c85
1 files changed, 50 insertions, 35 deletions
diff --git a/swaybar/main.c b/swaybar/main.c
index 7ac76dfa..243ef2a9 100644
--- a/swaybar/main.c
+++ b/swaybar/main.c
@@ -4,13 +4,14 @@
4#include <stdint.h> 4#include <stdint.h>
5#include <stdbool.h> 5#include <stdbool.h>
6#include <unistd.h> 6#include <unistd.h>
7#include <sys/select.h>
8#include <errno.h>
7#include <json-c/json.h> 9#include <json-c/json.h>
8#include <sys/un.h> 10#include <sys/un.h>
9#include <sys/socket.h> 11#include <sys/socket.h>
10#include <sys/ioctl.h> 12#include <sys/ioctl.h>
11#include <getopt.h> 13#include <getopt.h>
12#include "ipc-client.h" 14#include "ipc-client.h"
13#include "readline.h"
14#include "client/registry.h" 15#include "client/registry.h"
15#include "client/window.h" 16#include "client/window.h"
16#include "client/pango.h" 17#include "client/pango.h"
@@ -50,7 +51,8 @@ int socketfd;
50pid_t pid; 51pid_t pid;
51int pipefd[2]; 52int pipefd[2];
52FILE *command; 53FILE *command;
53char *line, *output, *status_command; 54char line[1024];
55char *output, *status_command;
54struct registry *registry; 56struct registry *registry;
55struct window *window; 57struct window *window;
56bool dirty = true; 58bool dirty = true;
@@ -106,7 +108,6 @@ void sway_terminate(void) {
106 close(pipefd[0]); 108 close(pipefd[0]);
107 } 109 }
108 110
109 free(line);
110 exit(EXIT_FAILURE); 111 exit(EXIT_FAILURE);
111} 112}
112 113
@@ -304,29 +305,6 @@ void bar_ipc_init(int outputi, const char *bar_id) {
304 ipc_update_workspaces(); 305 ipc_update_workspaces();
305} 306}
306 307
307void update() {
308 int pending;
309 // If no command is set, we don't have to update anything
310 if (status_command) {
311 if (ioctl(fileno(command), FIONREAD, &pending) != -1 && pending > 0) {
312 free(line);
313 line = read_line(command);
314 int l = strlen(line) - 1;
315 if (line[l] == '\n') {
316 line[l] = '\0';
317 }
318 dirty = true;
319 }
320 }
321 if (ioctl(socketfd, FIONREAD, &pending) != -1 && pending > 0) {
322 uint32_t len;
323 char *buf = ipc_recv_response(socketfd, &len);
324 free(buf);
325 ipc_update_workspaces();
326 dirty = true;
327 }
328}
329
330void render() { 308void render() {
331 // Clear 309 // Clear
332 cairo_save(window->cairo); 310 cairo_save(window->cairo);
@@ -379,6 +357,51 @@ void render() {
379 } 357 }
380} 358}
381 359
360void poll_for_update() {
361 fd_set readfds;
362 int activity;
363
364 while (1) {
365 if (dirty && window_prerender(window) && window->cairo) {
366 render();
367 window_render(window);
368 }
369
370 if (wl_display_dispatch(registry->display) == -1) {
371 break;
372 }
373
374 dirty = false;
375 FD_ZERO(&readfds);
376 FD_SET(socketfd, &readfds);
377 FD_SET(pipefd[0], &readfds);
378
379 activity = select(FD_SETSIZE, &readfds, NULL, NULL, NULL);
380 if (activity < 0) {
381 sway_log(L_ERROR, "polling failed: %d", errno);
382 }
383
384 if (FD_ISSET(socketfd, &readfds)) {
385 sway_log(L_DEBUG, "Got workspace update.");
386 uint32_t len;
387 char *buf = ipc_recv_response(socketfd, &len);
388 free(buf);
389 ipc_update_workspaces();
390 dirty = true;
391 }
392
393 if (status_command && FD_ISSET(pipefd[0], &readfds)) {
394 sway_log(L_DEBUG, "Got update from status command.");
395 fgets(line, sizeof(line), command);
396 int l = strlen(line) - 1;
397 if (line[l] == '\n') {
398 line[l] = '\0';
399 }
400 dirty = true;
401 }
402 }
403}
404
382int main(int argc, char **argv) { 405int main(int argc, char **argv) {
383 init_log(L_INFO); 406 init_log(L_INFO);
384 407
@@ -465,7 +488,6 @@ int main(int argc, char **argv) {
465 488
466 close(pipefd[1]); 489 close(pipefd[1]);
467 command = fdopen(pipefd[0], "r"); 490 command = fdopen(pipefd[0], "r");
468 line = malloc(1024);
469 line[0] = '\0'; 491 line[0] = '\0';
470 } 492 }
471 493
@@ -479,13 +501,7 @@ int main(int argc, char **argv) {
479 get_text_size(window, &width, &height, "Test string for measuring purposes"); 501 get_text_size(window, &width, &height, "Test string for measuring purposes");
480 window->height = height + MARGIN * 2; 502 window->height = height + MARGIN * 2;
481 503
482 do { 504 poll_for_update();
483 update();
484 if (dirty && window_prerender(window) && window->cairo) {
485 render();
486 window_render(window);
487 }
488 } while (wl_display_dispatch(registry->display) != -1);
489 505
490 window_teardown(window); 506 window_teardown(window);
491 registry_teardown(registry); 507 registry_teardown(registry);
@@ -493,7 +509,6 @@ int main(int argc, char **argv) {
493 // terminate status_command process 509 // terminate status_command process
494 kill(pid, SIGTERM); 510 kill(pid, SIGTERM);
495 close(pipefd[0]); 511 close(pipefd[0]);
496 free(line);
497 512
498 return 0; 513 return 0;
499} 514}