From 6c6607d404b0e8e886852537c382d3732f3454d7 Mon Sep 17 00:00:00 2001 From: Romain Vimont Date: Thu, 5 Dec 2024 21:02:50 +0100 Subject: [PATCH] Add --no-vd-destroy-content Add an option to disable the following flag for virtual displays: DisplayManager.VIRTUAL_DISPLAY_FLAG_DESTROY_CONTENT_ON_REMOVAL With this option, when the virtual display is closed, the running apps are moved to the main display rather than being destroyed. PR #5615 --- app/data/bash-completion/scrcpy | 1 + app/data/zsh-completion/_scrcpy | 1 + app/scrcpy.1 | 6 ++++++ app/src/cli.c | 13 +++++++++++++ app/src/options.c | 1 + app/src/options.h | 1 + app/src/scrcpy.c | 1 + app/src/server.c | 3 +++ app/src/server.h | 1 + doc/virtual_display.md | 11 +++++++++++ .../main/java/com/genymobile/scrcpy/Options.java | 8 ++++++++ .../genymobile/scrcpy/video/NewDisplayCapture.java | 8 ++++++-- 12 files changed, 53 insertions(+), 2 deletions(-) diff --git a/app/data/bash-completion/scrcpy b/app/data/bash-completion/scrcpy index 6c88927e0d..2913089216 100644 --- a/app/data/bash-completion/scrcpy +++ b/app/data/bash-completion/scrcpy @@ -57,6 +57,7 @@ _scrcpy() { --no-mipmaps --no-mouse-hover --no-power-on + --no-vd-destroy-content --no-vd-system-decorations --no-video --no-video-playback diff --git a/app/data/zsh-completion/_scrcpy b/app/data/zsh-completion/_scrcpy index e0c5e26518..0897b9ccd0 100644 --- a/app/data/zsh-completion/_scrcpy +++ b/app/data/zsh-completion/_scrcpy @@ -63,6 +63,7 @@ arguments=( '--no-mipmaps[Disable the generation of mipmaps]' '--no-mouse-hover[Do not forward mouse hover events]' '--no-power-on[Do not power on the device on start]' + '--no-vd-destroy-content[Disable virtual display "destroy content on removal" flag]' '--no-vd-system-decorations[Disable virtual display system decorations flag]' '--no-video[Disable video forwarding]' '--no-video-playback[Disable video playback]' diff --git a/app/scrcpy.1 b/app/scrcpy.1 index 326cb23f1c..924905e447 100644 --- a/app/scrcpy.1 +++ b/app/scrcpy.1 @@ -369,6 +369,12 @@ Do not forward mouse hover (mouse motion without any clicks) events. .B \-\-no\-power\-on Do not power on the device on start. +.TP +.B \-\-no\-vd\-destroy\-content +Disable virtual display "destroy content on removal" flag. + +With this option, when the virtual display is closed, the running apps are moved to the main display rather than being destroyed. + .TP .B \-\-no\-vd\-system\-decorations Disable virtual display system decorations flag. diff --git a/app/src/cli.c b/app/src/cli.c index cd0fa1c5b0..ed1970d472 100644 --- a/app/src/cli.c +++ b/app/src/cli.c @@ -110,6 +110,7 @@ enum { OPT_CAPTURE_ORIENTATION, OPT_ANGLE, OPT_NO_VD_SYSTEM_DECORATIONS, + OPT_NO_VD_DESTROY_CONTENT, }; struct sc_option { @@ -659,6 +660,15 @@ static const struct sc_option options[] = { .longopt = "no-power-on", .text = "Do not power on the device on start.", }, + { + .longopt_id = OPT_NO_VD_DESTROY_CONTENT, + .longopt = "no-vd-destroy-content", + .text = "Disable virtual display \"destroy content on removal\" " + "flag.\n" + "With this option, when the virtual display is closed, the " + "running apps are moved to the main display rather than being " + "destroyed.", + }, { .longopt_id = OPT_NO_VD_SYSTEM_DECORATIONS, .longopt = "no-vd-system-decorations", @@ -2705,6 +2715,9 @@ parse_args_with_getopt(struct scrcpy_cli_args *args, int argc, char *argv[], case OPT_ANGLE: opts->angle = optarg; break; + case OPT_NO_VD_DESTROY_CONTENT: + opts->vd_destroy_content = false; + break; case OPT_NO_VD_SYSTEM_DECORATIONS: opts->vd_system_decorations = false; break; diff --git a/app/src/options.c b/app/src/options.c index be3cf8d113..df8033e93c 100644 --- a/app/src/options.c +++ b/app/src/options.c @@ -108,6 +108,7 @@ const struct scrcpy_options scrcpy_options_default = { .new_display = NULL, .start_app = NULL, .angle = NULL, + .vd_destroy_content = true, .vd_system_decorations = true, }; diff --git a/app/src/options.h b/app/src/options.h index eaeba2f262..152881d840 100644 --- a/app/src/options.h +++ b/app/src/options.h @@ -310,6 +310,7 @@ struct scrcpy_options { bool audio_dup; const char *new_display; // [x][/] parsed by the server const char *start_app; + bool vd_destroy_content; bool vd_system_decorations; }; diff --git a/app/src/scrcpy.c b/app/src/scrcpy.c index dc9e237f37..f1942e436f 100644 --- a/app/src/scrcpy.c +++ b/app/src/scrcpy.c @@ -458,6 +458,7 @@ scrcpy(struct scrcpy_options *options) { .power_on = options->power_on, .kill_adb_on_close = options->kill_adb_on_close, .camera_high_speed = options->camera_high_speed, + .vd_destroy_content = options->vd_destroy_content, .vd_system_decorations = options->vd_system_decorations, .list = options->list, }; diff --git a/app/src/server.c b/app/src/server.c index 8bdf9501c3..22ddd3722d 100644 --- a/app/src/server.c +++ b/app/src/server.c @@ -377,6 +377,9 @@ execute_server(struct sc_server *server, VALIDATE_STRING(params->new_display); ADD_PARAM("new_display=%s", params->new_display); } + if (!params->vd_destroy_content) { + ADD_PARAM("vd_destroy_content=false"); + } if (!params->vd_system_decorations) { ADD_PARAM("vd_system_decorations=false"); } diff --git a/app/src/server.h b/app/src/server.h index 6d9dbd4d49..3c78b9edce 100644 --- a/app/src/server.h +++ b/app/src/server.h @@ -69,6 +69,7 @@ struct sc_server_params { bool power_on; bool kill_adb_on_close; bool camera_high_speed; + bool vd_destroy_content; bool vd_system_decorations; uint8_t list; }; diff --git a/doc/virtual_display.md b/doc/virtual_display.md index 5036f35b92..5d1673e869 100644 --- a/doc/virtual_display.md +++ b/doc/virtual_display.md @@ -50,3 +50,14 @@ any default launcher UI available in virtual displays. Note that if no app is started, no content will be rendered, so no video frame will be produced at all. + + +## Destroy on close + +By default, when the virtual display is closed, the running apps are destroyed. + +To move them to the main display instead, use: + +``` +scrcpy --new-display --no-vd-destroy-content +``` diff --git a/server/src/main/java/com/genymobile/scrcpy/Options.java b/server/src/main/java/com/genymobile/scrcpy/Options.java index 43cc790d13..8a43875078 100644 --- a/server/src/main/java/com/genymobile/scrcpy/Options.java +++ b/server/src/main/java/com/genymobile/scrcpy/Options.java @@ -60,6 +60,7 @@ public class Options { private boolean powerOn = true; private NewDisplay newDisplay; + private boolean vdDestroyContent = true; private boolean vdSystemDecorations = true; private Orientation.Lock captureOrientationLock = Orientation.Lock.Unlocked; @@ -233,6 +234,10 @@ public Orientation.Lock getCaptureOrientationLock() { return captureOrientationLock; } + public boolean getVDDestroyContent() { + return vdDestroyContent; + } + public boolean getVDSystemDecorations() { return vdSystemDecorations; } @@ -466,6 +471,9 @@ public static Options parse(String... args) { case "new_display": options.newDisplay = parseNewDisplay(value); break; + case "vd_destroy_content": + options.vdDestroyContent = Boolean.parseBoolean(value); + break; case "vd_system_decorations": options.vdSystemDecorations = Boolean.parseBoolean(value); break; diff --git a/server/src/main/java/com/genymobile/scrcpy/video/NewDisplayCapture.java b/server/src/main/java/com/genymobile/scrcpy/video/NewDisplayCapture.java index d92141af54..033d6b9a8c 100644 --- a/server/src/main/java/com/genymobile/scrcpy/video/NewDisplayCapture.java +++ b/server/src/main/java/com/genymobile/scrcpy/video/NewDisplayCapture.java @@ -53,6 +53,7 @@ public class NewDisplayCapture extends SurfaceCapture { private final boolean captureOrientationLocked; private final Orientation captureOrientation; private final float angle; + private final boolean vdDestroyContent; private final boolean vdSystemDecorations; private VirtualDisplay virtualDisplay; @@ -73,6 +74,7 @@ public NewDisplayCapture(VirtualDisplayListener vdListener, Options options) { this.captureOrientation = options.getCaptureOrientation(); assert captureOrientation != null; this.angle = options.getAngle(); + this.vdDestroyContent = options.getVDDestroyContent(); this.vdSystemDecorations = options.getVDSystemDecorations(); } @@ -167,8 +169,10 @@ public void startNew(Surface surface) { int flags = VIRTUAL_DISPLAY_FLAG_PUBLIC | VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY | VIRTUAL_DISPLAY_FLAG_SUPPORTS_TOUCH - | VIRTUAL_DISPLAY_FLAG_ROTATES_WITH_CONTENT - | VIRTUAL_DISPLAY_FLAG_DESTROY_CONTENT_ON_REMOVAL; + | VIRTUAL_DISPLAY_FLAG_ROTATES_WITH_CONTENT; + if (vdDestroyContent) { + flags |= VIRTUAL_DISPLAY_FLAG_DESTROY_CONTENT_ON_REMOVAL; + } if (vdSystemDecorations) { flags |= VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS; }