mirror of
https://github.com/swaywm/sway.git
synced 2024-11-22 07:51:28 +00:00
swaybar: rewrite protocol determination
This now uses the getline function to receive the header, replacing read_line_buffer, which has been deleted since it is otherwise unused. Furthermore, once the protocol has been determined, the current status is handled immediately to be shown (though this has not been added for the i3bar protocol since it has not yet been rewritten to handle this).
This commit is contained in:
parent
70245c2cd5
commit
8cbce77e1d
|
@ -70,28 +70,3 @@ char *peek_line(FILE *file, int line_offset, long *position) {
|
||||||
fseek(file, pos, SEEK_SET);
|
fseek(file, pos, SEEK_SET);
|
||||||
return line;
|
return line;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *read_line_buffer(FILE *file, char *string, size_t string_len) {
|
|
||||||
size_t length = 0;
|
|
||||||
if (!string) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
while (1) {
|
|
||||||
int c = getc(file);
|
|
||||||
if (c == EOF || c == '\n' || c == '\0') {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (c == '\r') {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
string[length++] = c;
|
|
||||||
if (string_len <= length) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (length + 1 == string_len) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
string[length] = '\0';
|
|
||||||
return string;
|
|
||||||
}
|
|
||||||
|
|
|
@ -31,7 +31,6 @@ void status_error(struct status_line *status, const char *text) {
|
||||||
|
|
||||||
bool status_handle_readable(struct status_line *status) {
|
bool status_handle_readable(struct status_line *status) {
|
||||||
ssize_t read_bytes = 1;
|
ssize_t read_bytes = 1;
|
||||||
char *line;
|
|
||||||
switch (status->protocol) {
|
switch (status->protocol) {
|
||||||
case PROTOCOL_I3BAR:
|
case PROTOCOL_I3BAR:
|
||||||
if (i3bar_handle_readable(status) > 0) {
|
if (i3bar_handle_readable(status) > 0) {
|
||||||
|
@ -39,36 +38,37 @@ bool status_handle_readable(struct status_line *status) {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PROTOCOL_UNDEF:
|
case PROTOCOL_UNDEF:
|
||||||
line = read_line_buffer(status->read,
|
errno = 0;
|
||||||
status->buffer, status->buffer_size);
|
read_bytes = getline(&status->buffer,
|
||||||
if (!line) {
|
&status->buffer_size, status->read);
|
||||||
|
if (errno == EAGAIN) {
|
||||||
|
clearerr(status->read);
|
||||||
|
} else if (errno) {
|
||||||
status_error(status, "[error reading from status command]");
|
status_error(status, "[error reading from status command]");
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
if (line[0] == '{') {
|
|
||||||
json_object *proto = json_tokener_parse(line);
|
// the header must be sent completely the first time round
|
||||||
if (proto) {
|
json_object *header, *version;
|
||||||
json_object *version;
|
if (status->buffer[read_bytes - 1] == '\n'
|
||||||
if (json_object_object_get_ex(proto, "version", &version)
|
&& (header = json_tokener_parse(status->buffer))
|
||||||
&& json_object_get_int(version) == 1) {
|
&& json_object_object_get_ex(header, "version", &version)
|
||||||
wlr_log(WLR_DEBUG, "Switched to i3bar protocol.");
|
&& json_object_get_int(version) == 1) {
|
||||||
status->protocol = PROTOCOL_I3BAR;
|
wlr_log(WLR_DEBUG, "Using i3bar protocol.");
|
||||||
|
status->protocol = PROTOCOL_I3BAR;
|
||||||
|
|
||||||
|
json_object *click_events;
|
||||||
|
if (json_object_object_get_ex(header, "click_events", &click_events)
|
||||||
|
&& json_object_get_boolean(click_events)) {
|
||||||
|
wlr_log(WLR_DEBUG, "Enabling click events.");
|
||||||
|
status->i3bar_state.click_events = true;
|
||||||
|
if (write(status->write_fd, "[\n", 2) != 2) {
|
||||||
|
status_error(status, "[failed to write to status command]");
|
||||||
|
json_object_put(header);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
json_object *click_events;
|
|
||||||
if (json_object_object_get_ex(
|
|
||||||
proto, "click_events", &click_events)
|
|
||||||
&& json_object_get_boolean(click_events)) {
|
|
||||||
wlr_log(WLR_DEBUG, "Enabled click events.");
|
|
||||||
status->i3bar_state.click_events = true;
|
|
||||||
const char *events_array = "[\n";
|
|
||||||
ssize_t len = strlen(events_array);
|
|
||||||
if (write(status->write_fd, events_array, len) != len) {
|
|
||||||
status_error(status,
|
|
||||||
"[failed to write to status command]");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
json_object_put(proto);
|
|
||||||
}
|
}
|
||||||
|
json_object_put(header);
|
||||||
|
|
||||||
status->protocol = PROTOCOL_I3BAR;
|
status->protocol = PROTOCOL_I3BAR;
|
||||||
free(status->buffer);
|
free(status->buffer);
|
||||||
|
@ -76,11 +76,13 @@ bool status_handle_readable(struct status_line *status) {
|
||||||
status->i3bar_state.buffer_size = 4096;
|
status->i3bar_state.buffer_size = 4096;
|
||||||
status->i3bar_state.buffer =
|
status->i3bar_state.buffer =
|
||||||
malloc(status->i3bar_state.buffer_size);
|
malloc(status->i3bar_state.buffer_size);
|
||||||
} else {
|
return false;
|
||||||
status->protocol = PROTOCOL_TEXT;
|
|
||||||
status->text = line;
|
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
|
wlr_log(WLR_DEBUG, "Using text protocol.");
|
||||||
|
status->protocol = PROTOCOL_TEXT;
|
||||||
|
status->text = status->buffer;
|
||||||
|
// intentional fall-through
|
||||||
case PROTOCOL_TEXT:
|
case PROTOCOL_TEXT:
|
||||||
errno = 0;
|
errno = 0;
|
||||||
while (true) {
|
while (true) {
|
||||||
|
|
Loading…
Reference in a new issue