How a Desktop Becomes Android Input

A fast picture does not make scrcpy interactive by itself. The separate question is how a keyboard press, mouse movement, touch, shortcut, or clipboard change crosses from the host computer to the Android system, and which interpretation Android gives it when it arrives. This chapter follows that control path and compares scrcpy's input modes so a person can choose between ordinary API injection, physical-HID behavior, wireless reach, and USB control without debugging access.

The control path carries actions, not pixels

On the host, scrcpy receives events through its desktop input layer. A key press, mouse motion, scroll, gesture, or shortcut is converted into a control message describing an Android action. The host does not write that event directly into a video stream. A controller thread takes messages from a queue, serializes them, and sends them on the control socket. This separation keeps the main window loop focused on receiving desktop events instead of waiting for network I/O or Android processing to finish.

The Android side receives the message through the same logical control channel and dispatches it to the appropriate action. Keycodes and text become keyboard input. Mouse and touch messages become motion events. Scroll becomes Android scrolling. Other messages can request actions such as going back, opening a panel, changing display power, rotating the device, starting an application, or resizing a virtual display. The Android controller owns the translation from the message's intent to the framework operation that can perform it.

The control socket is bidirectional. The host sends actions, but Android can send device messages back. Clipboard synchronization is the most visible example. When the Android clipboard changes, the server can notify the host; when the person asks to paste computer text into Android, the host sends a request in the opposite direction. That return path is why control is not just a one-way remote button channel. It is a small feedback loop attached to the larger media bridge.

The queue matters because not all actions have the same value. A mouse can produce a long sequence of motion events while a person drags across the screen. If every old motion event waits in line, the cursor may arrive at a location that was relevant several moments ago. scrcpy bounds its ordinary control queue and can discard droppable high-frequency messages when it is full. Messages that should not be casually discarded are handled differently where possible. Display resize is coalesced separately, so a series of intermediate window sizes does not force Android to process every transient state.

This is a responsiveness policy, not a claim that events can never be lost. Under normal conditions, the queue keeps the control path from growing without limit. Under severe host or transport pressure, dropping stale motion is often less harmful than delaying current motion, while dropping a command such as a power change or clipboard operation would be more surprising. The policy reflects the meaning of each event rather than treating all bytes as equally important.

The same principle explains why video and control should not share one undifferentiated queue. Video can arrive in bursts and may be buffered or decoded on its own schedule. A control message should usually be judged by whether it is still timely. By giving control its own socket and thread, scrcpy limits one kind of work from blocking the other at the application level. A saturated cable or a failing ADB connection can still affect the whole session, but the software does not add an avoidable dependency between a frame decoder and a mouse event.