From 42c641a110c93f3c52ece1bc1d3667b138227124 Mon Sep 17 00:00:00 2001 From: nightmare Date: Sun, 18 Aug 2024 19:37:47 +0800 Subject: [PATCH] add dispatch_to_vd option to server Fix input event do not work when screen virtual display --- .../java/com/genymobile/scrcpy/Options.java | 9 ++++++++ .../com/genymobile/scrcpy/device/Device.java | 23 +++++++++++++++++-- .../scrcpy/video/ScreenCapture.java | 3 +++ 3 files changed, 33 insertions(+), 2 deletions(-) diff --git a/server/src/main/java/com/genymobile/scrcpy/Options.java b/server/src/main/java/com/genymobile/scrcpy/Options.java index 2f86d8ce52..b47db6ba83 100644 --- a/server/src/main/java/com/genymobile/scrcpy/Options.java +++ b/server/src/main/java/com/genymobile/scrcpy/Options.java @@ -58,6 +58,8 @@ public class Options { private boolean listDisplays; private boolean listCameras; private boolean listCameraSizes; + // when screen virtual display, input event should be dispatched to virtual display + private boolean dispatchToVD = false; // Options not used by the scrcpy client, but useful to use scrcpy-server directly private boolean sendDeviceMeta = true; // send device name and size @@ -209,6 +211,10 @@ public boolean getList() { return listEncoders || listDisplays || listCameras || listCameraSizes; } + public boolean getDispatchToVD() { + return dispatchToVD; + } + public boolean getListEncoders() { return listEncoders; } @@ -388,6 +394,9 @@ public static Options parse(String... args) { case "list_camera_sizes": options.listCameraSizes = Boolean.parseBoolean(value); break; + case "dispatch_to_vd": + options.dispatchToVD = Boolean.parseBoolean(value); + break; case "camera_id": if (!value.isEmpty()) { options.cameraId = value; diff --git a/server/src/main/java/com/genymobile/scrcpy/device/Device.java b/server/src/main/java/com/genymobile/scrcpy/device/Device.java index 5a1083fded..273ac88b5c 100644 --- a/server/src/main/java/com/genymobile/scrcpy/device/Device.java +++ b/server/src/main/java/com/genymobile/scrcpy/device/Device.java @@ -64,6 +64,7 @@ public interface ClipboardListener { * Logical display identifier */ private final int displayId; + private int inputDisplayId; /** * The surface flinger layer stack associated with this logical display @@ -72,8 +73,15 @@ public interface ClipboardListener { private final boolean supportsInputEvents; + /** + * Whether to dispatch input events to the virtual display + */ + private final boolean dispatchToVD; + public Device(Options options) throws ConfigurationException { displayId = options.getDisplayId(); + inputDisplayId = displayId; + dispatchToVD = options.getDispatchToVD(); DisplayInfo displayInfo = ServiceManager.getDisplayManager().getDisplayInfo(displayId); if (displayInfo == null) { Ln.e("Display " + displayId + " not found\n" + LogUtils.buildDisplayListMessage()); @@ -172,6 +180,14 @@ public int getDisplayId() { return displayId; } + public int getInputDisplayId() { + return inputDisplayId; + } + + public void setInputDisplayId(int id) { + inputDisplayId = id; + } + public synchronized void setMaxSize(int newMaxSize) { maxSize = newMaxSize; screenInfo = ScreenInfo.computeScreenInfo(screenInfo.getReverseVideoRotation(), deviceSize, crop, newMaxSize, lockVideoOrientation); @@ -222,11 +238,14 @@ public boolean supportsInputEvents() { return supportsInputEvents; } + public boolean isDispatchToVD() { + return dispatchToVD; + } + public static boolean injectEvent(InputEvent inputEvent, int displayId, int injectMode) { if (!supportsInputEvents(displayId)) { throw new AssertionError("Could not inject input event if !supportsInputEvents()"); } - if (displayId != 0 && !InputManager.setDisplayId(inputEvent, displayId)) { return false; } @@ -235,7 +254,7 @@ public static boolean injectEvent(InputEvent inputEvent, int displayId, int inje } public boolean injectEvent(InputEvent event, int injectMode) { - return injectEvent(event, displayId, injectMode); + return injectEvent(event, inputDisplayId, injectMode); } public static boolean injectKeyEvent(int action, int keyCode, int repeat, int metaState, int displayId, int injectMode) { diff --git a/server/src/main/java/com/genymobile/scrcpy/video/ScreenCapture.java b/server/src/main/java/com/genymobile/scrcpy/video/ScreenCapture.java index fbeca2af07..1783acad6f 100644 --- a/server/src/main/java/com/genymobile/scrcpy/video/ScreenCapture.java +++ b/server/src/main/java/com/genymobile/scrcpy/video/ScreenCapture.java @@ -52,6 +52,9 @@ public void start(Surface surface) { virtualDisplay = ServiceManager.getDisplayManager() .createVirtualDisplay("scrcpy", videoRect.width(), videoRect.height(), device.getDisplayId(), surface); Ln.d("Display: using DisplayManager API"); + if (device.isDispatchToVD()) { + device.setInputDisplayId(virtualDisplay.getDisplay().getDisplayId()); + } } catch (Exception displayManagerException) { try { display = createDisplay();