Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support smooth scrolling on notebook touchpads. #3369

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion FAQ.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,20 @@ You could overwrite the `adb` binary in the other program, or ask _scrcpy_ to
use a specific `adb` binary, by setting the `ADB` environment variable:

```bash
set ADB=/path/to/your/adb
# in bash
export ADB=/path/to/your/adb
scrcpy
```

```cmd
:: in cmd
set ADB=C:\path\to\your\adb.exe
scrcpy
```

```powershell
# in PowerShell
$env:ADB = 'C:\path\to\your\adb.exe'
scrcpy
```

Expand Down
39 changes: 39 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -505,10 +505,23 @@ Suppose that this server is accessible at 192.168.1.2. Then, from another
terminal, run `scrcpy`:

```bash
# in bash
export ADB_SERVER_SOCKET=tcp:192.168.1.2:5037
scrcpy --tunnel-host=192.168.1.2
```

```cmd
:: in cmd
set ADB_SERVER_SOCKET=tcp:192.168.1.2:5037
scrcpy --tunnel-host=192.168.1.2
```

```powershell
# in PowerShell
$env:ADB_SERVER_SOCKET = 'tcp:192.168.1.2:5037'
scrcpy --tunnel-host=192.168.1.2
```

By default, `scrcpy` uses the local port used for `adb forward` tunnel
establishment (typically `27183`, see `--port`). It is also possible to force a
different tunnel port (it may be useful in more complex situations, when more
Expand Down Expand Up @@ -542,10 +555,23 @@ ssh -CN -L5038:localhost:5037 -R27183:localhost:27183 your_remote_computer
From another terminal, run `scrcpy`:

```bash
# in bash
export ADB_SERVER_SOCKET=tcp:localhost:5038
scrcpy
```

```cmd
:: in cmd
set ADB_SERVER_SOCKET=tcp:localhost:5038
scrcpy
```

```powershell
# in PowerShell
$env:ADB_SERVER_SOCKET = 'tcp:localhost:5038'
scrcpy
```

To avoid enabling remote port forwarding, you could force a forward connection
instead (notice the `-L` instead of `-R`):

Expand All @@ -559,10 +585,23 @@ ssh -CN -L5038:localhost:5037 -L27183:localhost:27183 your_remote_computer
From another terminal, run `scrcpy`:

```bash
# in bash
export ADB_SERVER_SOCKET=tcp:localhost:5038
scrcpy --force-adb-forward
```

```cmd
:: in cmd
set ADB_SERVER_SOCKET=tcp:localhost:5038
scrcpy --force-adb-forward
```

```powershell
# in PowerShell
$env:ADB_SERVER_SOCKET = 'tcp:localhost:5038'
scrcpy --force-adb-forward
```


Like for wireless connections, it may be useful to reduce quality:

Expand Down
21 changes: 12 additions & 9 deletions app/src/control_msg.c
Original file line number Diff line number Diff line change
Expand Up @@ -115,12 +115,15 @@ sc_control_msg_serialize(const struct sc_control_msg *msg, unsigned char *buf) {
return 28;
case SC_CONTROL_MSG_TYPE_INJECT_SCROLL_EVENT:
write_position(&buf[1], &msg->inject_scroll_event.position);
sc_write32be(&buf[13],
(uint32_t) msg->inject_scroll_event.hscroll);
sc_write32be(&buf[17],
(uint32_t) msg->inject_scroll_event.vscroll);
sc_write32be(&buf[21], msg->inject_scroll_event.buttons);
return 25;
// map [-1, 1] to [0, 1], then to uint16
uint16_t hscroll =
to_fixed_point_16((msg->inject_scroll_event.hscroll + 1.0f) / 2.0f);
rom1v marked this conversation as resolved.
Show resolved Hide resolved
uint16_t vscroll =
to_fixed_point_16((msg->inject_scroll_event.vscroll + 1.0f) / 2.0f);
sc_write16be(&buf[13], hscroll);
sc_write16be(&buf[15], vscroll);
sc_write32be(&buf[17], msg->inject_scroll_event.buttons);
return 21;
case SC_CONTROL_MSG_TYPE_BACK_OR_SCREEN_ON:
buf[1] = msg->inject_keycode.action;
return 2;
Expand Down Expand Up @@ -180,7 +183,7 @@ sc_control_msg_log(const struct sc_control_msg *msg) {
} else {
// numeric pointer id
LOG_CMSG("touch [id=%" PRIu64_ "] %-4s position=%" PRIi32 ",%"
PRIi32 " pressure=%g buttons=%06lx",
PRIi32 " pressure=%f buttons=%06lx",
rom1v marked this conversation as resolved.
Show resolved Hide resolved
id,
MOTIONEVENT_ACTION_LABEL(action),
msg->inject_touch_event.position.point.x,
Expand All @@ -191,8 +194,8 @@ sc_control_msg_log(const struct sc_control_msg *msg) {
break;
}
case SC_CONTROL_MSG_TYPE_INJECT_SCROLL_EVENT:
LOG_CMSG("scroll position=%" PRIi32 ",%" PRIi32 " hscroll=%" PRIi32
" vscroll=%" PRIi32 " buttons=%06lx",
LOG_CMSG("scroll position=%" PRIi32 ",%" PRIi32 " hscroll=%f"
" vscroll=%f buttons=%06lx",
msg->inject_scroll_event.position.point.x,
msg->inject_scroll_event.position.point.y,
msg->inject_scroll_event.hscroll,
Expand Down
4 changes: 2 additions & 2 deletions app/src/control_msg.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,8 @@ struct sc_control_msg {
} inject_touch_event;
struct {
struct sc_position position;
int32_t hscroll;
int32_t vscroll;
float hscroll;
float vscroll;
enum android_motionevent_buttons buttons;
} inject_scroll_event;
struct {
Expand Down
4 changes: 2 additions & 2 deletions app/src/input_events.h
Original file line number Diff line number Diff line change
Expand Up @@ -358,8 +358,8 @@ struct sc_mouse_click_event {

struct sc_mouse_scroll_event {
struct sc_position position;
int32_t hscroll;
int32_t vscroll;
float hscroll;
float vscroll;
uint8_t buttons_state; // bitwise-OR of sc_mouse_button values
};

Expand Down
16 changes: 14 additions & 2 deletions app/src/input_manager.c
Original file line number Diff line number Diff line change
Expand Up @@ -741,14 +741,26 @@ sc_input_manager_process_mouse_wheel(struct sc_input_manager *im,
int mouse_y;
uint32_t buttons = SDL_GetMouseState(&mouse_x, &mouse_y);

float hscroll;
float vscroll;
if (SDL_VERSION_ATLEAST(2, 0, 18)) {
// right is positive
hscroll = CLAMP(-event->preciseX, -1.0f, 1.0f);
// up is positive
vscroll = CLAMP(event->preciseY, -1.0f, 1.0f);
} else {
hscroll = CLAMP(-event->x, -1, 1);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nowadays the horizontal scrolling is actually inverted, so negated x and preciseX.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmmm, looks suspicious. See #966 (comment)

Copy link
Contributor Author

@yume-chan yume-chan Jul 24, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have seen that issue before, but this also happens to mouses with horizontal scrolling wheels.

Windows also has a touchpad scrolling direction setting, but whatever it was set, vertical scrolling is always correct and horizontal scrolling is always inverted.

I will test on a mac tomorrow.

Copy link
Contributor Author

@yume-chan yume-chan Jul 25, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Confirmed it's also inverted on macOS when using a mouse. My mac doesn't has touchpad so can't test that.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the value of event->direction in each case?

Concretely, could you list for each case (mouse/touchpad on windows/macOS):

  • event->direction
  • event->x
  • event->y
  • "inverted" or "not inverted"

cc @fsw0422 as the author of #966 (I do not want to break the fix for #966)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I won't be with my mac until Friday, will try that later.

vscroll = CLAMP(event->y, -1, 1);
}

struct sc_mouse_scroll_event evt = {
.position = {
.screen_size = im->screen->frame_size,
.point = sc_screen_convert_window_to_frame_coords(im->screen,
mouse_x, mouse_y),
},
.hscroll = event->x,
.vscroll = event->y,
.hscroll = hscroll,
.vscroll = vscroll,
.buttons_state =
sc_mouse_buttons_state_from_sdl(buttons, im->forward_all_clicks),
};
Expand Down
10 changes: 5 additions & 5 deletions server/src/main/java/com/genymobile/scrcpy/ControlMessage.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ public final class ControlMessage {
private long pointerId;
private float pressure;
private Position position;
private int hScroll;
private int vScroll;
private float hScroll;
private float vScroll;
private int copyKey;
private boolean paste;
private int repeat;
Expand Down Expand Up @@ -71,7 +71,7 @@ public static ControlMessage createInjectTouchEvent(int action, long pointerId,
return msg;
}

public static ControlMessage createInjectScrollEvent(Position position, int hScroll, int vScroll, int buttons) {
public static ControlMessage createInjectScrollEvent(Position position, float hScroll, float vScroll, int buttons) {
ControlMessage msg = new ControlMessage();
msg.type = TYPE_INJECT_SCROLL_EVENT;
msg.position = position;
Expand Down Expand Up @@ -156,11 +156,11 @@ public Position getPosition() {
return position;
}

public int getHScroll() {
public float getHScroll() {
return hScroll;
}

public int getVScroll() {
public float getVScroll() {
return vScroll;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ public class ControlMessageReader {

static final int INJECT_KEYCODE_PAYLOAD_LENGTH = 13;
static final int INJECT_TOUCH_EVENT_PAYLOAD_LENGTH = 27;
static final int INJECT_SCROLL_EVENT_PAYLOAD_LENGTH = 24;
static final int INJECT_SCROLL_EVENT_PAYLOAD_LENGTH = 20;
static final int BACK_OR_SCREEN_ON_LENGTH = 1;
static final int SET_SCREEN_POWER_MODE_PAYLOAD_LENGTH = 1;
static final int GET_CLIPBOARD_LENGTH = 1;
Expand Down Expand Up @@ -152,8 +152,10 @@ private ControlMessage parseInjectScrollEvent() {
return null;
}
Position position = readPosition(buffer);
int hScroll = buffer.getInt();
int vScroll = buffer.getInt();
int hScrollInt = toUnsigned(buffer.getShort());
int vScrollInt = toUnsigned(buffer.getShort());
float hScroll = hScrollInt == 0xffff ? 1f : ((hScrollInt - 0x8000) / 0x1p15f);
float vScroll = vScrollInt == 0xffff ? 1f : ((vScrollInt - 0x8000) / 0x1p15f);
int buttons = buffer.getInt();
return ControlMessage.createInjectScrollEvent(position, hScroll, vScroll, buttons);
}
Expand Down
2 changes: 1 addition & 1 deletion server/src/main/java/com/genymobile/scrcpy/Controller.java
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ private boolean injectTouch(int action, long pointerId, Position position, float
return device.injectEvent(event, Device.INJECT_MODE_ASYNC);
}

private boolean injectScroll(Position position, int hScroll, int vScroll, int buttons) {
private boolean injectScroll(Position position, float hScroll, float vScroll, int buttons) {
long now = SystemClock.uptimeMillis();
Point point = device.getPhysicalPoint(position);
if (point == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,8 +126,8 @@ public void testParseScrollEvent() throws IOException {
dos.writeInt(1026);
dos.writeShort(1080);
dos.writeShort(1920);
dos.writeInt(1);
dos.writeInt(-1);
dos.writeShort(0x8000);
dos.writeShort(0);
dos.writeInt(1);

byte[] packet = bos.toByteArray();
Expand All @@ -143,8 +143,8 @@ public void testParseScrollEvent() throws IOException {
Assert.assertEquals(1026, event.getPosition().getPoint().getY());
Assert.assertEquals(1080, event.getPosition().getScreenSize().getWidth());
Assert.assertEquals(1920, event.getPosition().getScreenSize().getHeight());
Assert.assertEquals(1, event.getHScroll());
Assert.assertEquals(-1, event.getVScroll());
Assert.assertEquals(0f, event.getHScroll(), 0f);
Assert.assertEquals(-1f, event.getVScroll(), 0f);
Assert.assertEquals(1, event.getButtons());
}

Expand Down