Genymobile / scrcpy

Display and control your Android device
Apache License 2.0
107.54k stars 10.39k forks source link

Unable to create window on sway desktop environment and crashes #4760

Open KairuiLiu opened 5 months ago

KairuiLiu commented 5 months ago

Environment

Describe the bug

On Sway (Wayland) desktop environment, when I try to run scrcpy, a window flashes on the screen and then immediately disappears. I attempted to limit the window resolution with --max-size=1080, and also tried to set windows with title=scrcpy and title=GM1910 to floating mode, but these attempts were unsuccessful.

❯ scrcpy -Vdebug

scrcpy 2.4 <https://github.com/Genymobile/scrcpy>
INFO: ADB device found:
INFO:     -->   (usb)  72800be1                        device  GM1910
DEBUG: Device serial: 72800be1
DEBUG: Using server: /usr/share/scrcpy/scrcpy-server
/usr/share/scrcpy/scrcpy-server: 1 file pushed, 0 skipped. 290.2 MB/s (69007 bytes in 0.000s)
[server] INFO: Device: [OnePlus] OnePlus GM1910 (Android 10)
[server] WARN: Audio disabled: it is not supported before Android 11
[server] DEBUG: Audio encoder stopped
DEBUG: Server connected
DEBUG: Starting controller thread
DEBUG: Starting receiver thread
[server] DEBUG: Using video encoder: 'OMX.qcom.video.encoder.avc'
INFO: Renderer: opengl
INFO: OpenGL version: 4.6 (Compatibility Profile) Mesa 24.0.2-arch1.2
INFO: Trilinear filtering enabled
DEBUG: Using icon: /usr/share/icons/hicolor/256x256/apps/scrcpy.png
DEBUG: Demuxer 'video': starting thread
DEBUG: Demuxer 'audio': starting thread
WARN: Demuxer 'audio': stream explicitly disabled by the device
INFO: Texture: 1440x3120
[server] DEBUG: Display: using SurfaceControl API
wp_viewport@35: error 2: source rectangle out of buffer bounds
DEBUG: User requested to quit
DEBUG: quit...
DEBUG: Demuxer 'video': end of frames
DEBUG: Receiver stopped
[server] DEBUG: Controller stopped
[server] DEBUG: Device message sender stopped
[server] DEBUG: Screen streaming stopped
DEBUG: Server disconnected
DEBUG: Server terminated
❯ scrcpy -Vdebug --max-size=1080

scrcpy 2.4 <https://github.com/Genymobile/scrcpy>
INFO: ADB device found:
INFO:     -->   (usb)  72800be1                        device  GM1910
DEBUG: Device serial: 72800be1
DEBUG: Using server: /usr/share/scrcpy/scrcpy-server
/usr/share/scrcpy/scrcpy-server: 1 file pushed, 0 skipped. 244.5 MB/s (69007 bytes in 0.000s)
[server] INFO: Device: [OnePlus] OnePlus GM1910 (Android 10)
[server] WARN: Audio disabled: it is not supported before Android 11
[server] DEBUG: Audio encoder stopped
DEBUG: Server connected
DEBUG: Starting controller thread
DEBUG: Starting receiver thread
[server] DEBUG: Using video encoder: 'OMX.qcom.video.encoder.avc'
INFO: Renderer: opengl
INFO: OpenGL version: 4.6 (Compatibility Profile) Mesa 24.0.2-arch1.2
INFO: Trilinear filtering enabled
DEBUG: Using icon: /usr/share/icons/hicolor/256x256/apps/scrcpy.png
DEBUG: Demuxer 'video': starting thread
DEBUG: Demuxer 'audio': starting thread
WARN: Demuxer 'audio': stream explicitly disabled by the device
INFO: Texture: 496x1080
[server] DEBUG: Display: using SurfaceControl API
wp_viewport@35: error 2: source rectangle out of buffer bounds
DEBUG: User requested to quit
DEBUG: quit...
DEBUG: Demuxer 'video': end of frames
DEBUG: Receiver stopped
[server] DEBUG: Controller stopped
[server] DEBUG: Device message sender stopped
[server] DEBUG: Screen streaming stopped
DEBUG: Server disconnected
DEBUG: Server terminated
❯ export SDL_VIDEODRIVER=wayland
scrcpy -Vdebug
scrcpy 2.4 <https://github.com/Genymobile/scrcpy>
INFO: ADB device found:
INFO:     -->   (usb)  72800be1                        device  GM1910
DEBUG: Device serial: 72800be1
DEBUG: Using server: /usr/share/scrcpy/scrcpy-server
/usr/share/scrcpy/scrcpy-server: 1 file pushed, 0 skipped. 403.8 MB/s (69007 bytes in 0.000s)
[server] INFO: Device: [OnePlus] OnePlus GM1910 (Android 10)
[server] WARN: Audio disabled: it is not supported before Android 11
[server] DEBUG: Audio encoder stopped
DEBUG: Server connected
DEBUG: Starting controller thread
DEBUG: Starting receiver thread
[server] DEBUG: Using video encoder: 'OMX.qcom.video.encoder.avc'
INFO: Renderer: opengl
INFO: OpenGL version: 4.6 (Compatibility Profile) Mesa 24.0.2-arch1.2
INFO: Trilinear filtering enabled
DEBUG: Using icon: /usr/share/icons/hicolor/256x256/apps/scrcpy.png
DEBUG: Demuxer 'video': starting thread
DEBUG: Demuxer 'audio': starting thread
WARN: Demuxer 'audio': stream explicitly disabled by the device
INFO: Texture: 1440x3120
[server] DEBUG: Display: using SurfaceControl API
wp_viewport@35: error 2: source rectangle out of buffer bounds
DEBUG: User requested to quit
DEBUG: quit...
DEBUG: Demuxer 'video': end of frames
DEBUG: Receiver stopped
[server] DEBUG: Controller stopped
[server] DEBUG: Device message sender stopped
[server] DEBUG: Screen streaming stopped
DEBUG: Server disconnected
DEBUG: Server terminated

In KDE Plasma environment, scrcpy displays as a very thin line (approximately 100x2 pixels) on the desktop. I can see the screen casting content only when I try to stretch this thin line.

rom1v commented 5 months ago

Looks similar to #3874.

In scrcpy, the window is created with a 0-sized hidden window, then it is resized when the first frame is received. Some SDL backends might not handle this correctly I guess.

Could you please add this log and retry, to see the actual size it uses:

diff --git a/app/src/screen.c b/app/src/screen.c
index 091001bcb..b3593950d 100644
--- a/app/src/screen.c
+++ b/app/src/screen.c
@@ -477,6 +477,9 @@ sc_screen_show_initial_window(struct sc_screen *screen) {
         get_initial_optimal_size(screen->content_size, screen->req.width,
                                                        screen->req.height);

+    LOGI("Set initial window size: %" PRIu16 "x%" PRIu16,
+         window_size.width, window_size.height);
+
     set_window_size(screen, window_size);
     SDL_SetWindowPosition(screen->window, x, y);

Also, does it work better if you pass an explicit size (just as a workaround):

scrcpy --window-width=400 --window-height=400
KairuiLiu commented 5 months ago

I'm sorry, I'm using a package built from the AUR, so it seems I can't modify files, but I've tried the following:

scrcpy --window-width=1080 --window-height=1920 -Vdebug

Sway crashed, Sway error log:

Errors from xkbcomp are not fatal to the X server
sway: render/pass.c:33: wlr_render_pass_add_texture: Assertion `box->x >= 0 && box->y >= 0 && box->x + box->width <= options->texture->width && box->y + box->height <= options->texture->height' failed.
[2024-03-16 01:04:43.793] [error] Window: Unable to receive IPC header
[2024-03-16 01:04:43.793] [error] Scratchpad: Unable to receive IPC header
[2024-03-16 01:04:43.793] [error] Window: Unable to receive IPC header
[2024-03-16 01:04:43.793] [error] Window: Unable to receive IPC header
[2024-03-16 01:04:43.793] [error] Scratchpad: Unable to receive IPC header
[2024-03-16 01:04:43.793] [error] Window: Unable to receive IPC header
[2024-03-16 01:04:43.793] [error] Scratchpad: Unable to receive IPC header
[2024-03-16 01:04:43.793] [error] Window: Unable to receive IPC header
[2024-03-16 01:04:43.793] [error] Scratchpad: Unable to receive IPC header
[2024-03-16 01:04:43.793] [error] Scratchpad: Unable to receive IPC header
[2024-03-16 01:04:43.793] [error] Scratchpad: Unable to receive IPC header
[2024-03-16 01:04:43.793] [error] Window: Unable to receive IPC header
[2024-03-16 01:04:43.793] [error] Scratchpad: Unable to receive IPC header
[2024-03-16 01:04:43.793] [error] Scratchpad: Unable to receive IPC header
[2024-03-16 01:04:43.793] [error] Scratchpad: Unable to receive IPC header
[2024-03-16 01:04:43.793] [error] Window: Unable to receive IPC header
[2024-03-16 01:04:43.793] [error] Scratchpad: Unable to receive IPC header
[2024-03-16 01:04:43.793] [error] Scratchpad: Unable to receive IPC header
[2024-03-16 01:04:43.793] [error] Scratchpad: Unable to receive IPC header
[2024-03-16 01:04:43.793] [error] Window: Unable to receive IPC header
[2024-03-16 01:04:43.793] [error] Scratchpad: Unable to receive IPC header
[2024-03-16 01:04:43.793] [error] Scratchpad: Unable to receive IPC header
[2024-03-16 01:04:43.793] [error] Scratchpad: Unable to receive IPC header
[2024-03-16 01:04:43.793] [error] Window: Unable to receive IPC header
Io error: [2024-03-16 01:04:43.793] [error] Scratchpad: Unable to receive IPC header
[2024-03-16 01:04:43.793] [error] Scratchpad: Unable to receive IPC header
[2024-03-16 01:04:43.793] [error] Scratchpad: Unable to receive IPC header
Broken pipe (os error 32[2024-03-16 01:04:43.793] [error] Scratchpad: Unable to receive IPC header
)
Io error: [2024-03-16 01:04:43.793] [error] Window: Unable to receive IPC header
[2024-03-16 01:04:43.793] [error] Scratchpad: Unable to receive IPC header
Broken pipe (os error [2024-03-16 01:04:43.793] [error] Scratchpad: Unable to receive IPC header
32)
[2024-03-16 01:04:43.793] [error] Scratchpad: Unable to receive IPC header
[2024-03-16 01:04:43.793] [error] Window: Unable to receive IPC header
[2024-03-16 01:04:43.793] [error] Scratchpad: Unable to receive IPC header
[2024-03-16 01:04:43.793] [error] Scratchpad: Unable to receive IPC header
[2024-03-16 01:04:43.793] [error] Window: Unable to receive IPC header
[2024-03-16 01:04:43.793] [error] Scratchpad: Unable to receive IPC header
[2024-03-16 01:04:43.793] [error] Scratchpad: Unable to receive IPC header
[2024-03-16 01:04:43.793] [error] Window: Unable to receive IPC header
[2024-03-16 01:04:43.793] [error] Window: Unable to receive IPC header
[2024-03-16 01:04:43.793] [error] Scratchpad: Unable to receive IPC header
[2024-03-16 01:04:43.793] [error] Scratchpad: Unable to receive IPC header
[2024-03-16 01:04:43.793] [error] Window: Unable to receive IPC header
[2024-03-16 01:04:43.793] [error] Window: Unable to receive IPC header
thread 'smithay-clipboard' panicked at /build/.cargo/registry/src/index.crates.io-6f17d22bba15001f/smithay-clipboard-0.7.0/src/worker.rs:98:47[2024-03-16 01:04:43.793] [error] Window: Unable to receive IPC header
:
called `Result::unwrap()` on an `Err` value: OtherError(IoError(Os { code: 32, kind: BrokenPipe, message: "Broken pipe" }))
[2024-03-16 01:04:43.793] [error] Workspaces: Unable to receive IPC header
[2024-03-16 01:04:43.793] [error] Window: Unable to receive IPC header
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Gdk-Message: 01:04:43.793: Error reading events from display: 断开的管道
[2024-03-16 01:04:43.793] [error] Window: Unable to receive IPC header
[2024-03-16 01:04:43.793] [error] Scratchpad: Unable to receive IPC header
[2024-03-16 01:04:43.793] [error] Workspaces: Unable to receive IPC header
[2024-03-16 01:04:43.793] [error] Scratchpad: Unable to receive IPC header
[2024-03-16 01:04:43.793] [error] Scratchpad: Unable to receive IPC header
[2024-03-16 01:04:43.793] [error] Scratchpad: Unable to receive IPC header
[2024-03-16 01:04:43.793] [error] Scratchpad: Unable to receive IPC header
[2024-03-16 01:04:43.793] [error] Scratchpad: Unable to receive IPC header
[2024-03-16 01:04:43.793] [error] Scratchpad: Unable to receive IPC header
[2024-03-16 01:04:43.793] [error] Scratchpad: Unable to receive IPC header
I[2024-03-16 01:04:43.793] [error] Scratchpad: Unable to receive IPC header
[2024-03-16 01:04:43.793] [error] Scratchpad: Unable to receive IPC header
2024-03-16 01:04:43.793233 [2024-03-16 01:04:43.793] [error] Scratchpad: Unable to receive IPC header
waylandmodule.cpp:[2024-03-16 01:04:43.793] [error] Scratchpad: Unable to receive IPC header
350] Connection removed 
[2024-03-16 01:04:43.793] [error] Scratchpad: Unable to receive IPC header
[2024-03-16 01:04:43.793] [error] Scratchpad: Unable to receive IPC header
[2024-03-16 01:04:43.793] [error] Scratchpad: Unable to receive IPC header
(EE) failed to read Wayland events: Broken pipe
Io error: Broken pipe (os error 32)
Error: ExitFailure(1)

If I add

export SDL_VIDEODRIVER=wayland
❯ scrcpy --window-width=1080 --window-height=1920 -Vdebug
scrcpy 2.4 <https://github.com/Genymobile/scrcpy>
INFO: ADB device found:
INFO:     -->   (usb)  653c0cb3                        device  2210132G
DEBUG: Device serial: 653c0cb3
DEBUG: Using server: /usr/share/scrcpy/scrcpy-server
/usr/share/scrcpy/scrcpy-server: 1 file pushed, 0 skipped. 72.0 MB/s (69007 bytes in 0.001s)
[server] INFO: Device: [Xiaomi] Xiaomi 2210132G (Android 14)
DEBUG: Server connected
DEBUG: Starting controller thread
DEBUG: Starting receiver thread
[server] DEBUG: Using video encoder: 'c2.qti.avc.encoder'
[server] DEBUG: Using audio encoder: 'c2.android.opus.encoder'
INFO: Renderer: opengl
INFO: OpenGL version: 4.6 (Compatibility Profile) Mesa 24.0.3-arch1.1
INFO: Trilinear filtering enabled
DEBUG: Using icon: /usr/share/icons/hicolor/256x256/apps/scrcpy.png
DEBUG: Demuxer 'video': starting thread
DEBUG: Demuxer 'audio': starting thread
INFO: Texture: 1080x2400
[server] DEBUG: Display: using SurfaceControl API
wp_viewport@35: error 2: source rectangle out of buffer bounds
DEBUG: User requested to quit
DEBUG: quit...
DEBUG: Receiver stopped
DEBUG: Demuxer 'audio': end of frames
DEBUG: Demuxer 'video': end of frames
[server] DEBUG: Controller stopped
[server] DEBUG: Device message sender stopped
[server] DEBUG: Screen streaming stopped
[server] DEBUG: Audio encoder stopped
DEBUG: Server disconnected
DEBUG: Server terminated

I also discovered an interesting issue: If I start a sway within sway and run scrcpy in this child sway, it runs normally. (maybe because it is showing on a virtual display?)

KairuiLiu commented 5 months ago

I applied the patch and completed the recompilation, but the problem persists. swappy-20240316_013238

❯ scrcpy --window-width=400 --window-height=400 -Vdebug
scrcpy 2.4 <https://github.com/Genymobile/scrcpy>
INFO: ADB device found:
INFO:     -->   (usb)  653c0cb3                        device  2210132G
DEBUG: Device serial: 653c0cb3
DEBUG: Using server: /usr/local/share/scrcpy/scrcpy-server
/usr/local/share/scrcpy/scrcpy-server: 1 file pushed, 0 skipped. 100.3 MB/s (69159 bytes in 0.001s)
[server] INFO: Device: [Xiaomi] Xiaomi 2210132G (Android 14)
DEBUG: Server connected
DEBUG: Starting controller thread
DEBUG: Starting receiver thread
[server] DEBUG: Using audio encoder: 'c2.android.opus.encoder'
[server] DEBUG: Using video encoder: 'c2.qti.avc.encoder'
INFO: Renderer: opengl
INFO: OpenGL version: 4.6 (Compatibility Profile) Mesa 24.0.3-arch1.1
INFO: Trilinear filtering enabled
DEBUG: Using icon: /usr/local/share/icons/hicolor/256x256/apps/scrcpy.png
DEBUG: Demuxer 'video': starting thread
DEBUG: Demuxer 'audio': starting thread
INFO: Texture: 1080x2400
[server] DEBUG: Display: using SurfaceControl API
INFO: Set initial window size: 400x400
wp_viewport@35: error 2: source rectangle out of buffer bounds
DEBUG: User requested to quit
DEBUG: quit...
DEBUG: Receiver stopped
ERROR: Demuxer 'audio': stream disabled due to connection error
DEBUG: Demuxer 'video': end of frames
[server] DEBUG: Controller stopped
[server] DEBUG: Device message sender stopped
[server] DEBUG: Audio encoder stopped
[server] DEBUG: Screen streaming stopped
DEBUG: Server disconnected
DEBUG: Server terminated
KairuiLiu commented 5 months ago

I made the following changes to the code. Currently it can run normally with parameters, but it will still crash without parameters.

image

rom1v commented 5 months ago

Could you please also report to SDL? They might know better what should be done.

KairuiLiu commented 5 months ago

It seems that there's no way to detect if it's running under a tiling window manager. I attempted to use the characteristic that a tiling window manager would forcibly change the window size to judge during initialization and resizing whether the command took effect, thereby determining the type of window manager. Unfortunately, it appears that changes in size are invisible to SDL. I tried to obtain the size during initialization and resizing, but the behavior is the same on both tiling (like sway) and non-tiling (like KDE) window managers. (When initializing with 0x0, I get 1x1, and during resize, the set and obtained values are the same). It looks like there's no better solution at the moment. If adding a startup parameter is too complicated, it seems that adding an environment variable SCRCPY_TILING_WM could be a simpler solution to the problem.

swappy-20240316_042726

Could you please also report to SDL? They might know better what should be done.

I will ask in the SDL project to see if there's a better way to address this.

KairuiLiu commented 5 months ago

According to feedback, SDL seems unable to resize windows under Wayland, which also explains why applications display only a thin line under KDE wayland.

The best solution would be for SDL to return an error message in this case, and for scrcpy to handle the error.

However, the most easy method seems to be for scrcpy to check if the SDL_VIDEODRIVER environment variable is set to Wayland, and if so, initialize the window with the parameters passed by the user|0 and then not perform any resizing.

This avoids adding a new calling parameter. If you think it's feasible, I'll submit a PR later.

StackDoubleFlow commented 5 months ago

Possibly related SDL issue: https://github.com/libsdl-org/SDL/issues/9283

chron-isch commented 4 months ago

For my laptop at least, this issue is resolved. I believe it can be closed if someone else can confirm it.

fleapower commented 2 months ago

I found this thread from another post. I'm having the same issue (Fedora 40, KDE w/ Wayland). Can anyone suggest the fix? Thanks!