Add get_clipbard ipc errors; Adapt swaymsg

Also increase the get_clipboard timeout to 30 secs
This commit is contained in:
nyorain 2017-07-11 18:04:24 +02:00
parent 20888fbb5e
commit 1cca551c6f
2 changed files with 47 additions and 18 deletions

View file

@ -365,7 +365,7 @@ static int ipc_selection_data_cb(int fd, uint32_t mask, void *data) {
if (mask & WLC_EVENT_ERROR) { if (mask & WLC_EVENT_ERROR) {
sway_log(L_ERROR, "Selection data fd error"); sway_log(L_ERROR, "Selection data fd error");
goto release; goto error;
} }
if (mask & WLC_EVENT_READABLE) { if (mask & WLC_EVENT_READABLE) {
@ -388,12 +388,12 @@ static int ipc_selection_data_cb(int fd, uint32_t mask, void *data) {
if (req->buf_position >= req->buf_size - 1) { if (req->buf_position >= req->buf_size - 1) {
if (req->buf_size >= max_size) { if (req->buf_size >= max_size) {
sway_log(L_ERROR, "get_clipbard: selection data too large"); sway_log(L_ERROR, "get_clipbard: selection data too large");
goto release; goto error;
} }
char *next = realloc(req->buf, req->buf_size *= 2); char *next = realloc(req->buf, req->buf_size *= 2);
if (!next) { if (!next) {
sway_log_errno(L_ERROR, "get_clipboard: realloc data buffer failed"); sway_log_errno(L_ERROR, "get_clipboard: realloc data buffer failed");
goto release; goto error;
} }
req->buf = next; req->buf = next;
@ -402,21 +402,33 @@ static int ipc_selection_data_cb(int fd, uint32_t mask, void *data) {
req->buf[req->buf_position] = '\0'; req->buf[req->buf_position] = '\0';
json_object *obj = json_object_new_object();
json_object_object_add(obj, "success", json_object_new_boolean(true));
if (is_text_target(req->type)) { if (is_text_target(req->type)) {
json_object_object_add(req->json, req->type, json_object_object_add(obj, "content", json_object_new_string(req->buf));
json_object_new_string(req->buf)); json_object_object_add(req->json, req->type, obj);
} else { } else {
size_t outlen; size_t outlen;
char *b64 = b64_encode(req->buf, req->buf_position, &outlen); char *b64 = b64_encode(req->buf, req->buf_position, &outlen);
json_object_object_add(obj, "content", json_object_new_string(b64));
free(b64);
char *type = malloc(strlen(req->type) + 8); char *type = malloc(strlen(req->type) + 8);
strcat(type, ";base64"); strcat(type, ";base64");
json_object_object_add(req->json, type, json_object_object_add(req->json, type, obj);
json_object_new_string(b64));
free(type); free(type);
free(b64);
} }
} }
goto release;
error:;
json_object *obj = json_object_new_object();
json_object_object_add(obj, "success", json_object_new_boolean(false));
json_object_object_add(obj, "error",
json_object_new_string("Failed to retrieve data"));
json_object_object_add(req->json, req->type, obj);
release: release:
release_clipboard_request(req); release_clipboard_request(req);
return 0; return 0;
@ -427,13 +439,18 @@ static int ipc_selection_timer_cb(void *data) {
struct get_clipboard_request *req = (struct get_clipboard_request *)data; struct get_clipboard_request *req = (struct get_clipboard_request *)data;
sway_log(L_INFO, "get_clipbard: timeout for type %s", req->type); sway_log(L_INFO, "get_clipbard: timeout for type %s", req->type);
json_object *obj = json_object_new_object();
json_object_object_add(obj, "success", json_object_new_boolean(false));
json_object_object_add(obj, "error", json_object_new_string("Timeout"));
json_object_object_add(req->json, req->type, obj);
release_clipboard_request(req); release_clipboard_request(req);
return 0; return 0;
} }
// greedy wildcard (only "*") matching // greedy wildcard (only "*") matching
bool mime_type_matches(const char *mime_type, const char *pattern) { bool mime_type_matches(const char *mime_type, const char *pattern) {
const char* wildcard = NULL; const char *wildcard = NULL;
while (*mime_type && *pattern) { while (*mime_type && *pattern) {
if (*pattern == '*' && !wildcard) { if (*pattern == '*' && !wildcard) {
wildcard = pattern; wildcard = pattern;
@ -461,9 +478,6 @@ bool mime_type_matches(const char *mime_type, const char *pattern) {
} }
void ipc_get_clipboard(struct ipc_client *client, char *buf) { void ipc_get_clipboard(struct ipc_client *client, char *buf) {
static const char *error_json = "{ \"success\": false, \"error\": "
"\"Failed to retrieve clipboard data\" }";
size_t size; size_t size;
const char **types = wlc_get_selection_types(&size); const char **types = wlc_get_selection_types(&size);
if (client->payload_length == 0) { if (client->payload_length == 0) {
@ -542,7 +556,7 @@ void ipc_get_clipboard(struct ipc_client *client, char *buf) {
WLC_EVENT_READABLE | WLC_EVENT_ERROR | WLC_EVENT_HANGUP, WLC_EVENT_READABLE | WLC_EVENT_ERROR | WLC_EVENT_HANGUP,
&ipc_selection_data_cb, req); &ipc_selection_data_cb, req);
wlc_event_source_timer_update(req->timer_event_source, 1000); wlc_event_source_timer_update(req->timer_event_source, 30000);
// NOTE: remove this goto to enable retrieving multiple // NOTE: remove this goto to enable retrieving multiple
// targets at once. The whole implementation is already // targets at once. The whole implementation is already
@ -561,15 +575,18 @@ void ipc_get_clipboard(struct ipc_client *client, char *buf) {
} }
if (*pending == 0) { if (*pending == 0) {
static const char *empty = "[]"; static const char *error_empty = "{ \"success\": false, \"error\": "
ipc_send_reply(client, empty, (uint32_t)strlen(empty)); "\"No matching types found\" }";
ipc_send_reply(client, error_empty, (uint32_t)strlen(error_empty));
free(json); free(json);
free(pending); free(pending);
} }
goto cleanup; goto cleanup;
data_error: data_error:;
static const char *error_json = "{ \"success\": false, \"error\": "
"\"Failed to create clipboard data request\" }";
ipc_send_reply(client, error_json, (uint32_t)strlen(error_json)); ipc_send_reply(client, error_json, (uint32_t)strlen(error_json));
free(json); free(json);
free(pending); free(pending);

View file

@ -160,10 +160,22 @@ static void pretty_print_clipboard(json_object *v) {
struct json_object_iterator iter = json_object_iter_begin(v); struct json_object_iterator iter = json_object_iter_begin(v);
struct json_object_iterator end = json_object_iter_end(v); struct json_object_iterator end = json_object_iter_end(v);
if (!json_object_iter_equal(&iter, &end)) { if (!json_object_iter_equal(&iter, &end)) {
printf("%s\n", json_object_get_string( json_object *obj = json_object_iter_peek_value(&iter);
json_object_iter_peek_value(&iter))); if (success(obj, false)) {
json_object *content;
json_object_object_get_ex(obj, "content", &content);
printf("%s\n", json_object_get_string(content));
} else {
json_object *error;
json_object_object_get_ex(obj, "error", &error);
printf("Error: %s\n", json_object_get_string(error));
}
} }
} }
} else {
json_object *error;
json_object_object_get_ex(v, "error", &error);
printf("Error: %s\n", json_object_get_string(error));
} }
} }