Compare commits
3 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
e31b13b0b2 | ||
|
2a7f3d70d7 | ||
|
94269ccaad |
20
README.md
20
README.md
@ -440,8 +440,12 @@ scrcpy -S
|
||||
|
||||
Or by pressing <kbd>MOD</kbd>+<kbd>o</kbd> at any time.
|
||||
|
||||
To turn it back on, press <kbd>MOD</kbd>+<kbd>Shift</kbd>+<kbd>o</kbd> (or
|
||||
`POWER`, <kbd>MOD</kbd>+<kbd>p</kbd>).
|
||||
To turn it back on, press <kbd>MOD</kbd>+<kbd>Shift</kbd>+<kbd>o</kbd>.
|
||||
|
||||
On Android, the `POWER` button always turns the screen on. For convenience, if
|
||||
`POWER` is sent via scrcpy (via right-click or <kbd>Ctrl</kbd>+<kbd>p</kbd>), it
|
||||
will force to turn the screen off after a small delay (on a best effort basis).
|
||||
The physical `POWER` button will still cause the screen to be turned on.
|
||||
|
||||
It can be useful to also prevent the device to sleep:
|
||||
|
||||
@ -558,6 +562,18 @@ scrcpy --prefer-text
|
||||
[prefertext]: https://github.com/Genymobile/scrcpy/issues/650#issuecomment-512945343
|
||||
|
||||
|
||||
#### Key repeat
|
||||
|
||||
By default, holding a key down generates repeated key events. This can cause
|
||||
performance problems in some games, where these events are useless anyway.
|
||||
|
||||
To avoid forwarding repeated key events:
|
||||
|
||||
```bash
|
||||
scrcpy --no-key-repeat
|
||||
```
|
||||
|
||||
|
||||
### File drop
|
||||
|
||||
#### Install APK
|
||||
|
@ -96,6 +96,10 @@ Do not display device (only when screen recording is enabled).
|
||||
.B \-\-no\-mipmaps
|
||||
If the renderer is OpenGL 3.0+ or OpenGL ES 2.0+, then mipmaps are automatically generated to improve downscaling quality. This option disables the generation of mipmaps.
|
||||
|
||||
.TP
|
||||
.B \-\-no\-key\-repeat
|
||||
Do not forward repeated key events when a key is held down.
|
||||
|
||||
.TP
|
||||
.BI "\-p, \-\-port " port[:port]
|
||||
Set the TCP port (range) used by the client to listen.
|
||||
|
@ -92,6 +92,9 @@ scrcpy_print_usage(const char *arg0) {
|
||||
" mipmaps are automatically generated to improve downscaling\n"
|
||||
" quality. This option disables the generation of mipmaps.\n"
|
||||
"\n"
|
||||
" --no-key-repeat\n"
|
||||
" Do not forward repeated key events when a key is held down.\n"
|
||||
"\n"
|
||||
" -p, --port port[:port]\n"
|
||||
" Set the TCP port (range) used by the client to listen.\n"
|
||||
" Default is %d:%d.\n"
|
||||
@ -642,6 +645,7 @@ guess_record_format(const char *filename) {
|
||||
#define OPT_FORCE_ADB_FORWARD 1019
|
||||
#define OPT_DISABLE_SCREENSAVER 1020
|
||||
#define OPT_SHORTCUT_MOD 1021
|
||||
#define OPT_NO_KEY_REPEAT 1022
|
||||
|
||||
bool
|
||||
scrcpy_parse_args(struct scrcpy_cli_args *args, int argc, char *argv[]) {
|
||||
@ -664,6 +668,7 @@ scrcpy_parse_args(struct scrcpy_cli_args *args, int argc, char *argv[]) {
|
||||
{"no-control", no_argument, NULL, 'n'},
|
||||
{"no-display", no_argument, NULL, 'N'},
|
||||
{"no-mipmaps", no_argument, NULL, OPT_NO_MIPMAPS},
|
||||
{"no-key-repeat", no_argument, NULL, OPT_NO_KEY_REPEAT},
|
||||
{"port", required_argument, NULL, 'p'},
|
||||
{"prefer-text", no_argument, NULL, OPT_PREFER_TEXT},
|
||||
{"push-target", required_argument, NULL, OPT_PUSH_TARGET},
|
||||
@ -829,6 +834,9 @@ scrcpy_parse_args(struct scrcpy_cli_args *args, int argc, char *argv[]) {
|
||||
case OPT_NO_MIPMAPS:
|
||||
opts->mipmaps = false;
|
||||
break;
|
||||
case OPT_NO_KEY_REPEAT:
|
||||
opts->forward_key_repeat = false;
|
||||
break;
|
||||
case OPT_CODEC_OPTIONS:
|
||||
opts->codec_options = optarg;
|
||||
break;
|
||||
|
@ -58,6 +58,7 @@ input_manager_init(struct input_manager *im,
|
||||
const struct scrcpy_options *options)
|
||||
{
|
||||
im->control = options->control;
|
||||
im->forward_key_repeat = options->forward_key_repeat;
|
||||
im->prefer_text = options->prefer_text;
|
||||
|
||||
const struct sc_shortcut_mods *shortcut_mods = &options->shortcut_mods;
|
||||
@ -461,6 +462,9 @@ input_manager_process_key(struct input_manager *im,
|
||||
}
|
||||
|
||||
if (event->repeat) {
|
||||
if (!im->forward_key_repeat) {
|
||||
return;
|
||||
}
|
||||
++im->repeat;
|
||||
} else {
|
||||
im->repeat = 0;
|
||||
|
@ -23,6 +23,7 @@ struct input_manager {
|
||||
unsigned repeat;
|
||||
|
||||
bool control;
|
||||
bool forward_key_repeat;
|
||||
bool prefer_text;
|
||||
|
||||
struct {
|
||||
|
@ -78,6 +78,7 @@ struct scrcpy_options {
|
||||
bool stay_awake;
|
||||
bool force_adb_forward;
|
||||
bool disable_screensaver;
|
||||
bool forward_key_repeat;
|
||||
};
|
||||
|
||||
#define SCRCPY_OPTIONS_DEFAULT { \
|
||||
@ -121,6 +122,7 @@ struct scrcpy_options {
|
||||
.stay_awake = false, \
|
||||
.force_adb_forward = false, \
|
||||
.disable_screensaver = false, \
|
||||
.forward_key_repeat = true, \
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -8,11 +8,16 @@ import android.view.KeyEvent;
|
||||
import android.view.MotionEvent;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class Controller {
|
||||
|
||||
private static final int DEVICE_ID_VIRTUAL = -1;
|
||||
|
||||
private static final ScheduledExecutorService EXECUTOR = Executors.newSingleThreadScheduledExecutor();
|
||||
|
||||
private final Device device;
|
||||
private final DesktopConnection connection;
|
||||
private final DeviceMessageSender sender;
|
||||
@ -24,6 +29,8 @@ public class Controller {
|
||||
private final MotionEvent.PointerProperties[] pointerProperties = new MotionEvent.PointerProperties[PointersState.MAX_POINTERS];
|
||||
private final MotionEvent.PointerCoords[] pointerCoords = new MotionEvent.PointerCoords[PointersState.MAX_POINTERS];
|
||||
|
||||
private boolean screenStayOff;
|
||||
|
||||
public Controller(Device device, DesktopConnection connection) {
|
||||
this.device = device;
|
||||
this.connection = connection;
|
||||
@ -117,6 +124,7 @@ public class Controller {
|
||||
int mode = msg.getAction();
|
||||
boolean setPowerModeOk = Device.setScreenPowerMode(mode);
|
||||
if (setPowerModeOk) {
|
||||
screenStayOff = mode == Device.POWER_MODE_OFF;
|
||||
Ln.i("Device screen turned " + (mode == Device.POWER_MODE_OFF ? "off" : "on"));
|
||||
}
|
||||
}
|
||||
@ -130,6 +138,9 @@ public class Controller {
|
||||
}
|
||||
|
||||
private boolean injectKeycode(int action, int keycode, int repeat, int metaState) {
|
||||
if (screenStayOff && action == KeyEvent.ACTION_UP && (keycode == KeyEvent.KEYCODE_POWER || keycode == KeyEvent.KEYCODE_WAKEUP)) {
|
||||
scheduleScreenOff();
|
||||
}
|
||||
return device.injectKeyEvent(action, keycode, repeat, metaState);
|
||||
}
|
||||
|
||||
@ -223,8 +234,24 @@ public class Controller {
|
||||
return device.injectEvent(event);
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule a call to turn the screen off after a small delay.
|
||||
*/
|
||||
private static void scheduleScreenOff() {
|
||||
EXECUTOR.schedule(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Ln.i("Forcing screen off");
|
||||
Device.setScreenPowerMode(Device.POWER_MODE_OFF);
|
||||
}
|
||||
}, 200, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
private boolean pressBackOrTurnScreenOn() {
|
||||
int keycode = device.isScreenOn() ? KeyEvent.KEYCODE_BACK : KeyEvent.KEYCODE_WAKEUP;
|
||||
if (screenStayOff && keycode == KeyEvent.KEYCODE_WAKEUP) {
|
||||
scheduleScreenOff();
|
||||
}
|
||||
return device.injectKeycode(keycode);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user