mirror of https://github.com/Genymobile/scrcpy
Add --pause-on-exit
Add an option to make scrcpy pause on exit. Three behaviors are possible: - always pause on exit: --pause-on-exit --pause-on-exit=true - never pause on exit: (no option) --pause-on-exit=false - pause when scrcpy returns with an error (a non-zero exit code): --pause-on-exit=if-error This is useful to prevent the terminal window from automatically closing, so that error messages can be read. Refs #3817 <https://github.com/Genymobile/scrcpy/pull/3817> Refs #3822 <https://github.com/Genymobile/scrcpy/pull/3822> PR #4130 <https://github.com/Genymobile/scrcpy/pull/4130>
This commit is contained in:
parent
a7c3c9a54c
commit
1650b7c058
|
@ -44,6 +44,8 @@ _scrcpy() {
|
|||
--no-video-playback
|
||||
--otg
|
||||
-p --port=
|
||||
--pause-on-exit
|
||||
--pause-on-exit=
|
||||
--power-off-on-close
|
||||
--prefer-text
|
||||
--print-fps
|
||||
|
@ -97,6 +99,10 @@ _scrcpy() {
|
|||
COMPREPLY=($(compgen -W 'unlocked initial 0 1 2 3' -- "$cur"))
|
||||
return
|
||||
;;
|
||||
--pause-on-exit)
|
||||
COMPREPLY=($(compgen -W 'true false if-error' -- "$cur"))
|
||||
return
|
||||
;;
|
||||
-r|--record)
|
||||
COMPREPLY=($(compgen -f -- "$cur"))
|
||||
return
|
||||
|
|
|
@ -50,6 +50,7 @@ arguments=(
|
|||
'--no-video-playback[Disable video playback]'
|
||||
'--otg[Run in OTG mode \(simulating physical keyboard and mouse\)]'
|
||||
{-p,--port=}'[\[port\[\:port\]\] Set the TCP port \(range\) used by the client to listen]'
|
||||
'--pause-on-exit=[Make scrcpy pause before exiting]:mode:(true false if-error)'
|
||||
'--power-off-on-close[Turn the device screen off when closing scrcpy]'
|
||||
'--prefer-text[Inject alpha characters and space as text events instead of key events]'
|
||||
'--print-fps[Start FPS counter, to print frame logs to the console]'
|
||||
|
|
10
app/scrcpy.1
10
app/scrcpy.1
|
@ -267,6 +267,16 @@ Set the TCP port (range) used by the client to listen.
|
|||
|
||||
Default is 27183:27199.
|
||||
|
||||
.TP
|
||||
\fB\-\-pause\-on\-exit\fR[=\fImode\fR]
|
||||
Configure pause on exit. Possible values are "true" (always pause on exit), "false" (never pause on exit) and "if-error" (pause only if an error occured).
|
||||
|
||||
This is useful to prevent the terminal window from automatically closing, so that error messages can be read.
|
||||
|
||||
Default is "false".
|
||||
|
||||
Passing the option without argument is equivalent to passing "true".
|
||||
|
||||
.TP
|
||||
.B \-\-power\-off\-on\-close
|
||||
Turn the device screen off when closing scrcpy.
|
||||
|
|
|
@ -79,6 +79,7 @@ enum {
|
|||
OPT_AUDIO_SOURCE,
|
||||
OPT_KILL_ADB_ON_CLOSE,
|
||||
OPT_TIME_LIMIT,
|
||||
OPT_PAUSE_ON_EXIT,
|
||||
};
|
||||
|
||||
struct sc_option {
|
||||
|
@ -463,6 +464,20 @@ static const struct sc_option options[] = {
|
|||
"Default is " STR(DEFAULT_LOCAL_PORT_RANGE_FIRST) ":"
|
||||
STR(DEFAULT_LOCAL_PORT_RANGE_LAST) ".",
|
||||
},
|
||||
{
|
||||
.longopt_id = OPT_PAUSE_ON_EXIT,
|
||||
.longopt = "pause-on-exit",
|
||||
.argdesc = "mode",
|
||||
.optional_arg = true,
|
||||
.text = "Configure pause on exit. Possible values are \"true\" (always "
|
||||
"pause on exit), \"false\" (never pause on exit) and "
|
||||
"\"if-error\" (pause only if an error occured).\n"
|
||||
"This is useful to prevent the terminal window from "
|
||||
"automatically closing, so that error messages can be read.\n"
|
||||
"Default is \"false\".\n"
|
||||
"Passing the option without argument is equivalent to passing "
|
||||
"\"true\".",
|
||||
},
|
||||
{
|
||||
.longopt_id = OPT_POWER_OFF_ON_CLOSE,
|
||||
.longopt = "power-off-on-close",
|
||||
|
@ -1637,6 +1652,29 @@ parse_time_limit(const char *s, sc_tick *tick) {
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
parse_pause_on_exit(const char *s, enum sc_pause_on_exit *pause_on_exit) {
|
||||
if (!s || !strcmp(s, "true")) {
|
||||
*pause_on_exit = SC_PAUSE_ON_EXIT_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!strcmp(s, "false")) {
|
||||
*pause_on_exit = SC_PAUSE_ON_EXIT_FALSE;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!strcmp(s, "if-error")) {
|
||||
*pause_on_exit = SC_PAUSE_ON_EXIT_IF_ERROR;
|
||||
return true;
|
||||
}
|
||||
|
||||
LOGE("Unsupported pause on exit mode: %s "
|
||||
"(expected true, false or if-error)", optarg);
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
static bool
|
||||
parse_args_with_getopt(struct scrcpy_cli_args *args, int argc, char *argv[],
|
||||
const char *optstring, const struct option *longopts) {
|
||||
|
@ -1977,6 +2015,11 @@ parse_args_with_getopt(struct scrcpy_cli_args *args, int argc, char *argv[],
|
|||
return false;
|
||||
}
|
||||
break;
|
||||
case OPT_PAUSE_ON_EXIT:
|
||||
if (!parse_pause_on_exit(optarg, &args->pause_on_exit)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// getopt prints the error message on stderr
|
||||
return false;
|
||||
|
@ -2190,6 +2233,37 @@ parse_args_with_getopt(struct scrcpy_cli_args *args, int argc, char *argv[],
|
|||
return true;
|
||||
}
|
||||
|
||||
static enum sc_pause_on_exit
|
||||
sc_get_pause_on_exit(int argc, char *argv[]) {
|
||||
// Read arguments backwards so that the last --pause-on-exit is considered
|
||||
// (same behavior as getopt())
|
||||
for (int i = argc - 1; i >= 1; --i) {
|
||||
const char *arg = argv[i];
|
||||
// Starts with "--pause-on-exit"
|
||||
if (!strncmp("--pause-on-exit", arg, 15)) {
|
||||
if (arg[15] == '\0') {
|
||||
// No argument
|
||||
return SC_PAUSE_ON_EXIT_TRUE;
|
||||
}
|
||||
if (arg[15] != '=') {
|
||||
// Invalid parameter, ignore
|
||||
return SC_PAUSE_ON_EXIT_FALSE;
|
||||
}
|
||||
const char *value = &arg[16];
|
||||
if (!strcmp(value, "true")) {
|
||||
return SC_PAUSE_ON_EXIT_TRUE;
|
||||
}
|
||||
if (!strcmp(value, "if-error")) {
|
||||
return SC_PAUSE_ON_EXIT_IF_ERROR;
|
||||
}
|
||||
// Set to false, inclusing when the value is invalid
|
||||
return SC_PAUSE_ON_EXIT_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
scrcpy_parse_args(struct scrcpy_cli_args *args, int argc, char *argv[]) {
|
||||
struct sc_getopt_adapter adapter;
|
||||
|
@ -2203,5 +2277,11 @@ scrcpy_parse_args(struct scrcpy_cli_args *args, int argc, char *argv[]) {
|
|||
|
||||
sc_getopt_adapter_destroy(&adapter);
|
||||
|
||||
if (!ret && args->pause_on_exit == SC_PAUSE_ON_EXIT_FALSE) {
|
||||
// Check if "--pause-on-exit" is present in the arguments list, because
|
||||
// it must be taken into account even if command line parsing failed
|
||||
args->pause_on_exit = sc_get_pause_on_exit(argc, argv);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -7,10 +7,17 @@
|
|||
|
||||
#include "options.h"
|
||||
|
||||
enum sc_pause_on_exit {
|
||||
SC_PAUSE_ON_EXIT_TRUE,
|
||||
SC_PAUSE_ON_EXIT_FALSE,
|
||||
SC_PAUSE_ON_EXIT_IF_ERROR,
|
||||
};
|
||||
|
||||
struct scrcpy_cli_args {
|
||||
struct scrcpy_options opts;
|
||||
bool help;
|
||||
bool version;
|
||||
enum sc_pause_on_exit pause_on_exit;
|
||||
};
|
||||
|
||||
void
|
||||
|
|
|
@ -39,26 +39,32 @@ main_scrcpy(int argc, char *argv[]) {
|
|||
.opts = scrcpy_options_default,
|
||||
.help = false,
|
||||
.version = false,
|
||||
.pause_on_exit = SC_PAUSE_ON_EXIT_FALSE,
|
||||
};
|
||||
|
||||
#ifndef NDEBUG
|
||||
args.opts.log_level = SC_LOG_LEVEL_DEBUG;
|
||||
#endif
|
||||
|
||||
enum scrcpy_exit_code ret;
|
||||
|
||||
if (!scrcpy_parse_args(&args, argc, argv)) {
|
||||
return SCRCPY_EXIT_FAILURE;
|
||||
ret = SCRCPY_EXIT_FAILURE;
|
||||
goto end;
|
||||
}
|
||||
|
||||
sc_set_log_level(args.opts.log_level);
|
||||
|
||||
if (args.help) {
|
||||
scrcpy_print_usage(argv[0]);
|
||||
return SCRCPY_EXIT_SUCCESS;
|
||||
ret = SCRCPY_EXIT_SUCCESS;
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (args.version) {
|
||||
scrcpy_print_version();
|
||||
return SCRCPY_EXIT_SUCCESS;
|
||||
ret = SCRCPY_EXIT_SUCCESS;
|
||||
goto end;
|
||||
}
|
||||
|
||||
#ifdef SCRCPY_LAVF_REQUIRES_REGISTER_ALL
|
||||
|
@ -72,18 +78,26 @@ main_scrcpy(int argc, char *argv[]) {
|
|||
#endif
|
||||
|
||||
if (!net_init()) {
|
||||
return SCRCPY_EXIT_FAILURE;
|
||||
ret = SCRCPY_EXIT_FAILURE;
|
||||
goto end;
|
||||
}
|
||||
|
||||
sc_log_configure();
|
||||
|
||||
#ifdef HAVE_USB
|
||||
enum scrcpy_exit_code ret = args.opts.otg ? scrcpy_otg(&args.opts)
|
||||
: scrcpy(&args.opts);
|
||||
ret = args.opts.otg ? scrcpy_otg(&args.opts) : scrcpy(&args.opts);
|
||||
#else
|
||||
enum scrcpy_exit_code ret = scrcpy(&args.opts);
|
||||
ret = scrcpy(&args.opts);
|
||||
#endif
|
||||
|
||||
end:
|
||||
if (args.pause_on_exit == SC_PAUSE_ON_EXIT_TRUE ||
|
||||
(args.pause_on_exit == SC_PAUSE_ON_EXIT_IF_ERROR &&
|
||||
ret != SCRCPY_EXIT_SUCCESS)) {
|
||||
printf("Press Enter to continue...\n");
|
||||
getchar();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue