Skip to content

Commit

Permalink
Accept positional control events without display
Browse files Browse the repository at this point in the history
The position of touch and scroll must normally be "resolved" with a
"position mapper" associated to the display.

But to support the injection of such events with scrcpy-server alone
without video, handle the case where there is no display.

Fixes #5542 <#5542>
  • Loading branch information
rom1v committed Nov 28, 2024
1 parent 4317ee3 commit 9f4dc10
Showing 1 changed file with 21 additions and 10 deletions.
31 changes: 21 additions & 10 deletions server/src/main/java/com/genymobile/scrcpy/control/Controller.java
Original file line number Diff line number Diff line change
Expand Up @@ -355,19 +355,30 @@ private Pair<Point, Integer> getEventPointAndDisplayId(Position position) {
// it hides the field on purpose, to read it with atomic access
@SuppressWarnings("checkstyle:HiddenField")
DisplayData displayData = this.displayData.get();
assert displayData != null : "Cannot receive a positional event without a display";

Point point = displayData.positionMapper.map(position);
if (point == null) {
if (Ln.isEnabled(Ln.Level.VERBOSE)) {
Size eventSize = position.getScreenSize();
Size currentSize = displayData.positionMapper.getVideoSize();
Ln.v("Ignore positional event generated for size " + eventSize + " (current size is " + currentSize + ")");
// In scrcpy, displayData should never be null (a touch event can only be generated from the client when a video frame is present).
// However, it is possible to send events without video playback when using scrcpy-server alone (except for virtual displays).
assert displayData != null || displayId != Device.DISPLAY_ID_NONE : "Cannot receive a positional event without a display";

Point point;
int targetDisplayId;
if (displayData != null) {
point = displayData.positionMapper.map(position);
if (point == null) {
if (Ln.isEnabled(Ln.Level.VERBOSE)) {
Size eventSize = position.getScreenSize();
Size currentSize = displayData.positionMapper.getVideoSize();
Ln.v("Ignore positional event generated for size " + eventSize + " (current size is " + currentSize + ")");
}
return null;
}
return null;
targetDisplayId = displayData.virtualDisplayId;
} else {
// No display, use the raw coordinates
point = position.getPoint();
targetDisplayId = displayId;
}

return Pair.create(point, displayData.virtualDisplayId);
return Pair.create(point, targetDisplayId);
}

private boolean injectTouch(int action, long pointerId, Position position, float pressure, int actionButton, int buttons) {
Expand Down

0 comments on commit 9f4dc10

Please sign in to comment.