Skip to content

Commit cf9d449

Browse files
brunoaisrom1v
authored andcommitted
Keep the screen off on powering on
PR #1577 <#1577> Fixes #1573 <#1573> Signed-off-by: Romain Vimont <rom@rom1v.com>
1 parent 84f1d9e commit cf9d449

File tree

2 files changed

+33
-2
lines changed

2 files changed

+33
-2
lines changed

README.md

+6-2
Original file line numberDiff line numberDiff line change
@@ -440,8 +440,12 @@ scrcpy -S
440440

441441
Or by pressing <kbd>MOD</kbd>+<kbd>o</kbd> at any time.
442442

443-
To turn it back on, press <kbd>MOD</kbd>+<kbd>Shift</kbd>+<kbd>o</kbd> (or
444-
`POWER`, <kbd>MOD</kbd>+<kbd>p</kbd>).
443+
To turn it back on, press <kbd>MOD</kbd>+<kbd>Shift</kbd>+<kbd>o</kbd>.
444+
445+
On Android, the `POWER` button always turns the screen on. For convenience, if
446+
`POWER` is sent via scrcpy (via right-click or <kbd>Ctrl</kbd>+<kbd>p</kbd>), it
447+
will force to turn the screen off after a small delay (on a best effort basis).
448+
The physical `POWER` button will still cause the screen to be turned on.
445449

446450
It can be useful to also prevent the device to sleep:
447451

server/src/main/java/com/genymobile/scrcpy/Controller.java

+27
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,16 @@
88
import android.view.MotionEvent;
99

1010
import java.io.IOException;
11+
import java.util.concurrent.Executors;
12+
import java.util.concurrent.ScheduledExecutorService;
13+
import java.util.concurrent.TimeUnit;
1114

1215
public class Controller {
1316

1417
private static final int DEVICE_ID_VIRTUAL = -1;
1518

19+
private static final ScheduledExecutorService EXECUTOR = Executors.newSingleThreadScheduledExecutor();
20+
1621
private final Device device;
1722
private final DesktopConnection connection;
1823
private final DeviceMessageSender sender;
@@ -24,6 +29,8 @@ public class Controller {
2429
private final MotionEvent.PointerProperties[] pointerProperties = new MotionEvent.PointerProperties[PointersState.MAX_POINTERS];
2530
private final MotionEvent.PointerCoords[] pointerCoords = new MotionEvent.PointerCoords[PointersState.MAX_POINTERS];
2631

32+
private boolean keepPowerModeOff;
33+
2734
public Controller(Device device, DesktopConnection connection) {
2835
this.device = device;
2936
this.connection = connection;
@@ -117,6 +124,7 @@ private void handleEvent() throws IOException {
117124
int mode = msg.getAction();
118125
boolean setPowerModeOk = Device.setScreenPowerMode(mode);
119126
if (setPowerModeOk) {
127+
keepPowerModeOff = mode == Device.POWER_MODE_OFF;
120128
Ln.i("Device screen turned " + (mode == Device.POWER_MODE_OFF ? "off" : "on"));
121129
}
122130
}
@@ -130,6 +138,9 @@ private void handleEvent() throws IOException {
130138
}
131139

132140
private boolean injectKeycode(int action, int keycode, int repeat, int metaState) {
141+
if (keepPowerModeOff && action == KeyEvent.ACTION_UP && (keycode == KeyEvent.KEYCODE_POWER || keycode == KeyEvent.KEYCODE_WAKEUP)) {
142+
schedulePowerModeOff();
143+
}
133144
return device.injectKeyEvent(action, keycode, repeat, metaState);
134145
}
135146

@@ -223,8 +234,24 @@ private boolean injectScroll(Position position, int hScroll, int vScroll) {
223234
return device.injectEvent(event);
224235
}
225236

237+
/**
238+
* Schedule a call to set power mode to off after a small delay.
239+
*/
240+
private static void schedulePowerModeOff() {
241+
EXECUTOR.schedule(new Runnable() {
242+
@Override
243+
public void run() {
244+
Ln.i("Forcing screen off");
245+
Device.setScreenPowerMode(Device.POWER_MODE_OFF);
246+
}
247+
}, 200, TimeUnit.MILLISECONDS);
248+
}
249+
226250
private boolean pressBackOrTurnScreenOn() {
227251
int keycode = device.isScreenOn() ? KeyEvent.KEYCODE_BACK : KeyEvent.KEYCODE_WAKEUP;
252+
if (keepPowerModeOff && keycode == KeyEvent.KEYCODE_WAKEUP) {
253+
schedulePowerModeOff();
254+
}
228255
return device.injectKeycode(keycode);
229256
}
230257

0 commit comments

Comments
 (0)