Set clipboard from the main thread
The clipboard changes from the device are received from a separate thread, but they must be handled from the main thread. PR #5270 <https://github.com/Genymobile/scrcpy/pull/5270>
This commit is contained in:
parent
8620d06741
commit
72ee195693
@ -6,8 +6,10 @@
|
|||||||
#include <SDL2/SDL_clipboard.h>
|
#include <SDL2/SDL_clipboard.h>
|
||||||
|
|
||||||
#include "device_msg.h"
|
#include "device_msg.h"
|
||||||
|
#include "events.h"
|
||||||
#include "util/log.h"
|
#include "util/log.h"
|
||||||
#include "util/str.h"
|
#include "util/str.h"
|
||||||
|
#include "util/thread.h"
|
||||||
|
|
||||||
bool
|
bool
|
||||||
sc_receiver_init(struct sc_receiver *receiver, sc_socket control_socket,
|
sc_receiver_init(struct sc_receiver *receiver, sc_socket control_socket,
|
||||||
@ -33,20 +35,39 @@ sc_receiver_destroy(struct sc_receiver *receiver) {
|
|||||||
sc_mutex_destroy(&receiver->mutex);
|
sc_mutex_destroy(&receiver->mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
task_set_clipboard(void *userdata) {
|
||||||
|
assert(sc_thread_get_id() == SC_MAIN_THREAD_ID);
|
||||||
|
|
||||||
|
char *text = userdata;
|
||||||
|
|
||||||
|
char *current = SDL_GetClipboardText();
|
||||||
|
bool same = current && !strcmp(current, text);
|
||||||
|
SDL_free(current);
|
||||||
|
if (same) {
|
||||||
|
LOGD("Computer clipboard unchanged");
|
||||||
|
} else {
|
||||||
|
LOGI("Device clipboard copied");
|
||||||
|
SDL_SetClipboardText(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(text);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
process_msg(struct sc_receiver *receiver, struct sc_device_msg *msg) {
|
process_msg(struct sc_receiver *receiver, struct sc_device_msg *msg) {
|
||||||
switch (msg->type) {
|
switch (msg->type) {
|
||||||
case DEVICE_MSG_TYPE_CLIPBOARD: {
|
case DEVICE_MSG_TYPE_CLIPBOARD: {
|
||||||
char *current = SDL_GetClipboardText();
|
// Take ownership of the text (do not destroy the msg)
|
||||||
bool same = current && !strcmp(current, msg->clipboard.text);
|
char *text = msg->clipboard.text;
|
||||||
SDL_free(current);
|
|
||||||
if (same) {
|
bool ok = sc_post_to_main_thread(task_set_clipboard, text);
|
||||||
LOGD("Computer clipboard unchanged");
|
if (!ok) {
|
||||||
|
LOGW("Could not post clipboard to main thread");
|
||||||
|
free(text);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOGI("Device clipboard copied");
|
|
||||||
SDL_SetClipboardText(msg->clipboard.text);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DEVICE_MSG_TYPE_ACK_CLIPBOARD:
|
case DEVICE_MSG_TYPE_ACK_CLIPBOARD:
|
||||||
@ -64,6 +85,7 @@ process_msg(struct sc_receiver *receiver, struct sc_device_msg *msg) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sc_acksync_ack(receiver->acksync, msg->ack_clipboard.sequence);
|
sc_acksync_ack(receiver->acksync, msg->ack_clipboard.sequence);
|
||||||
|
// No allocation to free in the msg
|
||||||
break;
|
break;
|
||||||
case DEVICE_MSG_TYPE_UHID_OUTPUT:
|
case DEVICE_MSG_TYPE_UHID_OUTPUT:
|
||||||
if (sc_get_log_level() <= SC_LOG_LEVEL_VERBOSE) {
|
if (sc_get_log_level() <= SC_LOG_LEVEL_VERBOSE) {
|
||||||
@ -86,6 +108,7 @@ process_msg(struct sc_receiver *receiver, struct sc_device_msg *msg) {
|
|||||||
// Also check at runtime (do not trust the server)
|
// Also check at runtime (do not trust the server)
|
||||||
if (!receiver->uhid_devices) {
|
if (!receiver->uhid_devices) {
|
||||||
LOGE("Received unexpected HID output message");
|
LOGE("Received unexpected HID output message");
|
||||||
|
sc_device_msg_destroy(msg);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,6 +122,8 @@ process_msg(struct sc_receiver *receiver, struct sc_device_msg *msg) {
|
|||||||
} else {
|
} else {
|
||||||
LOGW("No UHID receiver for id %" PRIu16, msg->uhid_output.id);
|
LOGW("No UHID receiver for id %" PRIu16, msg->uhid_output.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sc_device_msg_destroy(msg);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -117,7 +142,7 @@ process_msgs(struct sc_receiver *receiver, const uint8_t *buf, size_t len) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
process_msg(receiver, &msg);
|
process_msg(receiver, &msg);
|
||||||
sc_device_msg_destroy(&msg);
|
// the device msg must be destroyed by process_msg()
|
||||||
|
|
||||||
head += r;
|
head += r;
|
||||||
assert(head <= len);
|
assert(head <= len);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user