diff --git a/README.md b/README.md
index f355c7b6..fa4aff68 100644
--- a/README.md
+++ b/README.md
@@ -730,6 +730,9 @@ 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).
+To disable automatic clipboard synchronization, use
+`--no-clipboard-autosync`.
+
#### Pinch-to-zoom
To simulate "pinch-to-zoom": Ctrl+_click-and-move_.
diff --git a/app/scrcpy.1 b/app/scrcpy.1
index 7438118b..122af757 100644
--- a/app/scrcpy.1
+++ b/app/scrcpy.1
@@ -114,6 +114,12 @@ Limit both the width and height of the video to \fIvalue\fR. The other dimension
Default is 0 (unlimited).
+.TP
+.B \-\-no\-clipboard\-autosync
+By default, scrcpy automatically synchronizes the computer clipboard to the device clipboard before injecting Ctrl+v, and the device clipboard to the computer clipboard whenever it changes.
+
+This option disables this automatic synchronization.
+
.TP
.B \-n, \-\-no\-control
Disable device control (mirror the device in read\-only).
diff --git a/app/src/cli.c b/app/src/cli.c
index 5256d50e..29cb8932 100644
--- a/app/src/cli.c
+++ b/app/src/cli.c
@@ -49,6 +49,7 @@
#define OPT_V4L2_BUFFER 1029
#define OPT_TUNNEL_HOST 1030
#define OPT_TUNNEL_PORT 1031
+#define OPT_NO_CLIPBOARD_AUTOSYNC 1032
struct sc_option {
char shortopt;
@@ -208,6 +209,15 @@ static const struct sc_option options[] = {
"is preserved.\n"
"Default is 0 (unlimited).",
},
+ {
+ .longopt_id = OPT_NO_CLIPBOARD_AUTOSYNC,
+ .longopt = "no-clipboard-autosync",
+ .text = "By default, scrcpy automatically synchronizes the computer "
+ "clipboard to the device clipboard before injecting Ctrl+v, "
+ "and the device clipboard to the computer clipboard whenever "
+ "it changes.\n"
+ "This option disables this automatic synchronization."
+ },
{
.shortopt = 'n',
.longopt = "no-control",
@@ -1364,6 +1374,9 @@ parse_args_with_getopt(struct scrcpy_cli_args *args, int argc, char *argv[],
return false;
}
break;
+ case OPT_NO_CLIPBOARD_AUTOSYNC:
+ opts->clipboard_autosync = false;
+ break;
#ifdef HAVE_V4L2
case OPT_V4L2_SINK:
opts->v4l2_device = optarg;
diff --git a/app/src/input_manager.c b/app/src/input_manager.c
index f1715b79..31d6540f 100644
--- a/app/src/input_manager.c
+++ b/app/src/input_manager.c
@@ -66,6 +66,7 @@ input_manager_init(struct input_manager *im, struct controller *controller,
im->control = options->control;
im->forward_all_clicks = options->forward_all_clicks;
im->legacy_paste = options->legacy_paste;
+ im->clipboard_autosync = options->clipboard_autosync;
const struct sc_shortcut_mods *shortcut_mods = &options->shortcut_mods;
assert(shortcut_mods->count);
@@ -518,7 +519,7 @@ input_manager_process_key(struct input_manager *im,
uint64_t ack_to_wait = SC_SEQUENCE_INVALID;
bool is_ctrl_v = ctrl && !shift && keycode == SDLK_v && down && !repeat;
- if (is_ctrl_v) {
+ if (im->clipboard_autosync && is_ctrl_v) {
if (im->legacy_paste) {
// inject the text as input events
clipboard_paste(controller);
diff --git a/app/src/input_manager.h b/app/src/input_manager.h
index 22d77381..5e02b457 100644
--- a/app/src/input_manager.h
+++ b/app/src/input_manager.h
@@ -24,6 +24,7 @@ struct input_manager {
bool control;
bool forward_all_clicks;
bool legacy_paste;
+ bool clipboard_autosync;
struct {
unsigned data[SC_MAX_SHORTCUT_MODS];
diff --git a/app/src/options.c b/app/src/options.c
index 074bdf08..a99b09da 100644
--- a/app/src/options.c
+++ b/app/src/options.c
@@ -53,4 +53,5 @@ const struct scrcpy_options scrcpy_options_default = {
.forward_all_clicks = false,
.legacy_paste = false,
.power_off_on_close = false,
+ .clipboard_autosync = true,
};
diff --git a/app/src/options.h b/app/src/options.h
index 82d094cd..d10b2e8a 100644
--- a/app/src/options.h
+++ b/app/src/options.h
@@ -108,6 +108,7 @@ struct scrcpy_options {
bool forward_all_clicks;
bool legacy_paste;
bool power_off_on_close;
+ bool clipboard_autosync;
};
extern const struct scrcpy_options scrcpy_options_default;
diff --git a/app/src/scrcpy.c b/app/src/scrcpy.c
index 04239bf5..061a4e76 100644
--- a/app/src/scrcpy.c
+++ b/app/src/scrcpy.c
@@ -364,6 +364,7 @@ scrcpy(struct scrcpy_options *options) {
.encoder_name = options->encoder_name,
.force_adb_forward = options->force_adb_forward,
.power_off_on_close = options->power_off_on_close,
+ .clipboard_autosync = options->clipboard_autosync,
};
static const struct sc_server_callbacks cbs = {
diff --git a/app/src/server.c b/app/src/server.c
index 78127d2d..546216e9 100644
--- a/app/src/server.c
+++ b/app/src/server.c
@@ -186,6 +186,7 @@ execute_server(struct sc_server *server,
params->codec_options ? params->codec_options : "-",
params->encoder_name ? params->encoder_name : "-",
params->power_off_on_close ? "true" : "false",
+ params->clipboard_autosync ? "true" : "false",
};
#ifdef SERVER_DEBUGGER
LOGI("Server debugger waiting for a client on device port "
diff --git a/app/src/server.h b/app/src/server.h
index cb1fadbb..5b25ff46 100644
--- a/app/src/server.h
+++ b/app/src/server.h
@@ -41,6 +41,7 @@ struct sc_server_params {
bool stay_awake;
bool force_adb_forward;
bool power_off_on_close;
+ bool clipboard_autosync;
};
struct sc_server {
diff --git a/server/src/main/java/com/genymobile/scrcpy/Device.java b/server/src/main/java/com/genymobile/scrcpy/Device.java
index 093646e2..03ae9b22 100644
--- a/server/src/main/java/com/genymobile/scrcpy/Device.java
+++ b/server/src/main/java/com/genymobile/scrcpy/Device.java
@@ -82,8 +82,8 @@ public final class Device {
}
}, displayId);
- if (options.getControl()) {
- // If control is enabled, synchronize Android clipboard to the computer automatically
+ if (options.getControl() && options.getClipboardAutosync()) {
+ // If control and autosync are enabled, synchronize Android clipboard to the computer automatically
ClipboardManager clipboardManager = SERVICE_MANAGER.getClipboardManager();
if (clipboardManager != null) {
clipboardManager.addPrimaryClipChangedListener(new IOnPrimaryClipChangedListener.Stub() {
diff --git a/server/src/main/java/com/genymobile/scrcpy/Options.java b/server/src/main/java/com/genymobile/scrcpy/Options.java
index cf11df0f..74467c7c 100644
--- a/server/src/main/java/com/genymobile/scrcpy/Options.java
+++ b/server/src/main/java/com/genymobile/scrcpy/Options.java
@@ -18,6 +18,7 @@ public class Options {
private String codecOptions;
private String encoderName;
private boolean powerOffScreenOnClose;
+ private boolean clipboardAutosync;
public Ln.Level getLogLevel() {
return logLevel;
@@ -138,4 +139,12 @@ public class Options {
public boolean getPowerOffScreenOnClose() {
return this.powerOffScreenOnClose;
}
+
+ public boolean getClipboardAutosync() {
+ return clipboardAutosync;
+ }
+
+ public void setClipboardAutosync(boolean clipboardAutosync) {
+ this.clipboardAutosync = clipboardAutosync;
+ }
}
diff --git a/server/src/main/java/com/genymobile/scrcpy/Server.java b/server/src/main/java/com/genymobile/scrcpy/Server.java
index 5a1f4619..188974ff 100644
--- a/server/src/main/java/com/genymobile/scrcpy/Server.java
+++ b/server/src/main/java/com/genymobile/scrcpy/Server.java
@@ -160,7 +160,7 @@ public final class Server {
"The server version (" + BuildConfig.VERSION_NAME + ") does not match the client " + "(" + clientVersion + ")");
}
- final int expectedParameters = 16;
+ final int expectedParameters = 17;
if (args.length != expectedParameters) {
throw new IllegalArgumentException("Expecting " + expectedParameters + " parameters");
}
@@ -213,6 +213,9 @@ public final class Server {
boolean powerOffScreenOnClose = Boolean.parseBoolean(args[15]);
options.setPowerOffScreenOnClose(powerOffScreenOnClose);
+ boolean clipboardAutosync = Boolean.parseBoolean(args[16]);
+ options.setClipboardAutosync(clipboardAutosync);
+
return options;
}