diff --git a/README.md b/README.md
index a61407ac3a..95a38409df 100644
--- a/README.md
+++ b/README.md
@@ -548,6 +548,11 @@ into the device clipboard. As a consequence, any Android application could read
its content. You should avoid to paste sensitive content (like passwords) that
way.
+Some devices do not behave as expected when setting the device clipboard
+programmatically. An option `--legacy-paste` is provided to change the behavior
+of Ctrl+v and MOD+v so that they
+also inject the computer clipboard text as a sequence of key events (the same
+way as MOD+Shift+v).
#### Pinch-to-zoom
diff --git a/app/scrcpy.1 b/app/scrcpy.1
index e2b999deef..b16d1004c3 100644
--- a/app/scrcpy.1
+++ b/app/scrcpy.1
@@ -72,6 +72,12 @@ Start in fullscreen.
.B \-h, \-\-help
Print this help.
+.TP
+.B \-\-legacy\-paste
+Inject computer clipboard text as a sequence of key events on Ctrl+v (like MOD+Shift+v).
+
+This is a workaround for some devices not behaving as expected when setting the device clipboard programmatically.
+
.TP
.BI "\-\-lock\-video\-orientation " value
Lock video orientation to \fIvalue\fR. Possible values are -1 (unlocked), 0, 1, 2 and 3. Natural device orientation is 0, and each increment adds a 90 degrees otation counterclockwise.
diff --git a/app/src/cli.c b/app/src/cli.c
index ffe3145524..4f15f2e8d5 100644
--- a/app/src/cli.c
+++ b/app/src/cli.c
@@ -68,6 +68,12 @@ scrcpy_print_usage(const char *arg0) {
" -h, --help\n"
" Print this help.\n"
"\n"
+ " --legacy-paste\n"
+ " Inject computer clipboard text as a sequence of key events\n"
+ " on Ctrl+v (like MOD+Shift+v).\n"
+ " This is a workaround for some devices not behaving as\n"
+ " expected when setting the device clipboard programmatically.\n"
+ "\n"
" --lock-video-orientation value\n"
" Lock video orientation to value.\n"
" Possible values are -1 (unlocked), 0, 1, 2 and 3.\n"
@@ -657,6 +663,7 @@ guess_record_format(const char *filename) {
#define OPT_SHORTCUT_MOD 1021
#define OPT_NO_KEY_REPEAT 1022
#define OPT_FORWARD_ALL_CLICKS 1023
+#define OPT_LEGACY_PASTE 1024
bool
scrcpy_parse_args(struct scrcpy_cli_args *args, int argc, char *argv[]) {
@@ -674,6 +681,7 @@ scrcpy_parse_args(struct scrcpy_cli_args *args, int argc, char *argv[]) {
OPT_FORWARD_ALL_CLICKS},
{"fullscreen", no_argument, NULL, 'f'},
{"help", no_argument, NULL, 'h'},
+ {"legacy-paste", no_argument, NULL, OPT_LEGACY_PASTE},
{"lock-video-orientation", required_argument, NULL,
OPT_LOCK_VIDEO_ORIENTATION},
{"max-fps", required_argument, NULL, OPT_MAX_FPS},
@@ -867,6 +875,9 @@ scrcpy_parse_args(struct scrcpy_cli_args *args, int argc, char *argv[]) {
case OPT_FORWARD_ALL_CLICKS:
opts->forward_all_clicks = true;
break;
+ case OPT_LEGACY_PASTE:
+ opts->legacy_paste = true;
+ break;
default:
// getopt prints the error message on stderr
return false;
diff --git a/app/src/input_manager.c b/app/src/input_manager.c
index b03da38349..bab8566021 100644
--- a/app/src/input_manager.c
+++ b/app/src/input_manager.c
@@ -61,6 +61,7 @@ input_manager_init(struct input_manager *im,
im->forward_key_repeat = options->forward_key_repeat;
im->prefer_text = options->prefer_text;
im->forward_all_clicks = options->forward_all_clicks;
+ im->legacy_paste = options->legacy_paste;
const struct sc_shortcut_mods *shortcut_mods = &options->shortcut_mods;
assert(shortcut_mods->count);
@@ -441,7 +442,7 @@ input_manager_process_key(struct input_manager *im,
return;
case SDLK_v:
if (control && !repeat && down) {
- if (shift) {
+ if (shift || im->legacy_paste) {
// inject the text as input events
clipboard_paste(controller);
} else {
@@ -505,6 +506,11 @@ input_manager_process_key(struct input_manager *im,
}
if (ctrl && !shift && keycode == SDLK_v && down && !repeat) {
+ if (im->legacy_paste) {
+ // inject the text as input events
+ clipboard_paste(controller);
+ return;
+ }
// Synchronize the computer clipboard to the device clipboard before
// sending Ctrl+v, to allow seamless copy-paste.
set_device_clipboard(controller, false);
diff --git a/app/src/input_manager.h b/app/src/input_manager.h
index 157c28329d..df9b071fe5 100644
--- a/app/src/input_manager.h
+++ b/app/src/input_manager.h
@@ -26,6 +26,7 @@ struct input_manager {
bool forward_key_repeat;
bool prefer_text;
bool forward_all_clicks;
+ bool legacy_paste;
struct {
unsigned data[SC_MAX_SHORTCUT_MODS];
diff --git a/app/src/scrcpy.h b/app/src/scrcpy.h
index 8ab05a9dd6..5f761f75e5 100644
--- a/app/src/scrcpy.h
+++ b/app/src/scrcpy.h
@@ -80,6 +80,7 @@ struct scrcpy_options {
bool disable_screensaver;
bool forward_key_repeat;
bool forward_all_clicks;
+ bool legacy_paste;
};
#define SCRCPY_OPTIONS_DEFAULT { \
@@ -125,6 +126,7 @@ struct scrcpy_options {
.disable_screensaver = false, \
.forward_key_repeat = true, \
.forward_all_clicks = false, \
+ .legacy_paste = false, \
}
bool