aboutsummaryrefslogtreecommitdiffstats
path: root/swaybar/status_line.c
diff options
context:
space:
mode:
Diffstat (limited to 'swaybar/status_line.c')
-rw-r--r--swaybar/status_line.c64
1 files changed, 33 insertions, 31 deletions
diff --git a/swaybar/status_line.c b/swaybar/status_line.c
index 54a68b40..fcc0cb93 100644
--- a/swaybar/status_line.c
+++ b/swaybar/status_line.c
@@ -31,7 +31,6 @@ void status_error(struct status_line *status, const char *text) {
31 31
32bool status_handle_readable(struct status_line *status) { 32bool status_handle_readable(struct status_line *status) {
33 ssize_t read_bytes = 1; 33 ssize_t read_bytes = 1;
34 char *line;
35 switch (status->protocol) { 34 switch (status->protocol) {
36 case PROTOCOL_I3BAR: 35 case PROTOCOL_I3BAR:
37 if (i3bar_handle_readable(status) > 0) { 36 if (i3bar_handle_readable(status) > 0) {
@@ -39,36 +38,37 @@ bool status_handle_readable(struct status_line *status) {
39 } 38 }
40 break; 39 break;
41 case PROTOCOL_UNDEF: 40 case PROTOCOL_UNDEF:
42 line = read_line_buffer(status->read, 41 errno = 0;
43 status->buffer, status->buffer_size); 42 read_bytes = getline(&status->buffer,
44 if (!line) { 43 &status->buffer_size, status->read);
44 if (errno == EAGAIN) {
45 clearerr(status->read);
46 } else if (errno) {
45 status_error(status, "[error reading from status command]"); 47 status_error(status, "[error reading from status command]");
46 return false; 48 return true;
47 } 49 }
48 if (line[0] == '{') { 50
49 json_object *proto = json_tokener_parse(line); 51 // the header must be sent completely the first time round
50 if (proto) { 52 json_object *header, *version;
51 json_object *version; 53 if (status->buffer[read_bytes - 1] == '\n'
52 if (json_object_object_get_ex(proto, "version", &version) 54 && (header = json_tokener_parse(status->buffer))
53 && json_object_get_int(version) == 1) { 55 && json_object_object_get_ex(header, "version", &version)
54 wlr_log(WLR_DEBUG, "Switched to i3bar protocol."); 56 && json_object_get_int(version) == 1) {
55 status->protocol = PROTOCOL_I3BAR; 57 wlr_log(WLR_DEBUG, "Using i3bar protocol.");
56 } 58 status->protocol = PROTOCOL_I3BAR;
57 json_object *click_events; 59
58 if (json_object_object_get_ex( 60 json_object *click_events;
59 proto, "click_events", &click_events) 61 if (json_object_object_get_ex(header, "click_events", &click_events)
60 && json_object_get_boolean(click_events)) { 62 && json_object_get_boolean(click_events)) {
61 wlr_log(WLR_DEBUG, "Enabled click events."); 63 wlr_log(WLR_DEBUG, "Enabling click events.");
62 status->i3bar_state.click_events = true; 64 status->i3bar_state.click_events = true;
63 const char *events_array = "[\n"; 65 if (write(status->write_fd, "[\n", 2) != 2) {
64 ssize_t len = strlen(events_array); 66 status_error(status, "[failed to write to status command]");
65 if (write(status->write_fd, events_array, len) != len) { 67 json_object_put(header);
66 status_error(status, 68 return true;
67 "[failed to write to status command]");
68 }
69 } 69 }
70 json_object_put(proto);
71 } 70 }
71 json_object_put(header);
72 72
73 status->protocol = PROTOCOL_I3BAR; 73 status->protocol = PROTOCOL_I3BAR;
74 free(status->buffer); 74 free(status->buffer);
@@ -76,11 +76,13 @@ bool status_handle_readable(struct status_line *status) {
76 status->i3bar_state.buffer_size = 4096; 76 status->i3bar_state.buffer_size = 4096;
77 status->i3bar_state.buffer = 77 status->i3bar_state.buffer =
78 malloc(status->i3bar_state.buffer_size); 78 malloc(status->i3bar_state.buffer_size);
79 } else { 79 return false;
80 status->protocol = PROTOCOL_TEXT;
81 status->text = line;
82 } 80 }
83 return true; 81
82 wlr_log(WLR_DEBUG, "Using text protocol.");
83 status->protocol = PROTOCOL_TEXT;
84 status->text = status->buffer;
85 // intentional fall-through
84 case PROTOCOL_TEXT: 86 case PROTOCOL_TEXT:
85 errno = 0; 87 errno = 0;
86 while (true) { 88 while (true) {