neutrinolabs / xrdp

xrdp: an open source RDP server
http://www.xrdp.org/
Apache License 2.0
5.73k stars 1.73k forks source link

xrdp v0.10 incorrect behavior when minimizing and restoring a mstsc.exe connection in fullscreen with multiple monitors (v0.9 works fine) #3075

Closed pancro closed 4 months ago

pancro commented 5 months ago

xrdp version

0.10.0

Detailed xrdp version, build options

0.10.0

Operating system & version

various

Installation method

git clone & make install

Which backend do you use?

xorgxrdp

What desktop environment do you use?

i3 and GNOME

Environment xrdp running on

kvm virtual machine

What's your client?

Win11 mstsc.exe

Area(s) with issue?

Graphic glitches, Other

Steps to reproduce

In Summary, when you open a multi-monitor full-screen remote connection to xrdp 0.10, it's not possible to minimize and then maximize correctly the remote desktop connection: only one monitor is displayed when you maximize. The same workflow works correctly with xrdp 0.9.

Equipment utilized:

Reproducer:

✔️ Expected Behavior

❌ Actual Behavior

Anything else?

The workaround is to disconnect and reconnect, and the monitors are once again displayed correctly.

metalefty commented 5 months ago

Thanks for the detailed report. I'll try to reproduce.

metalefty commented 5 months ago

@pancro Just to be sure, could you let me know the exact commit hash or tag of both xrdp and xorgxrdp?

Also, can you increase the log level to DEBUG and see the log at the time:

metalefty commented 5 months ago

Received log in private as it may contain sensitive information.

metalefty commented 5 months ago

@matt335672 Could you try to reproduce this one?

matt335672 commented 5 months ago

I'll take a look but it may take me a while to get to it.

matt335672 commented 5 months ago

I can't reproduce this on Windows 10 mstsc.exe.

I'm not getting any drdynvc messages when I click the windows buttons. Nor would I expect any, as the client monitor configuration isn't changing.

I don't have a multi-screen Windows 11 machine. I'll try to knock up a VM with two screens later in the week.

matt335672 commented 5 months ago

I can't reproduce this on Windows 11 mstsc.exe either

Again, clicking the suggested buttons does not result in any client to server messages related to screen sizes being logged in xrdp.log.

@pancro - are you able to share any log details after clicking buttons?

Also, have you got any other display options set (e.g. scaling) which might be related to this?

derekschrock commented 5 months ago

I can produce this with only gfx connections (32 bit color). Changing the connection to 24 bit doesn't have the same issue and restores to full screen over all displays. Also, this only appears to be when you window/restore/maximize, minimizing doesn't seem to be a problem.

The three test cases all had identical resolution displays:

With the 1x2 it full restored full screen to a single display. With 2x2 it full screened to two (bottom two) displays. Windows 10 mstsc 10.0.19041.4355 (don't have the Windows 11 version right now - I'd assume something semi-new). This was all via the UI.

The server is running fully updated rocky9 with xrdp-0.10.0-3.el9.x86_64 and xorgxrdp-0.10.1-1.el9.x86_64 from epel9-testing and fvwm3 built from source.

metalefty commented 5 months ago

@derekschrock Thanks for the info, I didn't care the color depth. I will test again.

matt335672 commented 5 months ago

I've check my config, and I'm running 32-bit colour (this is a requirement for GFX). It's in the RDP config I posted above.

I've checked the XRDP log and I'm seeing GFX. This is on Windows 11 with two 1920x1080 monitors next to each other.

[2024-06-05T09:53:24.660+0100] [INFO ] [xrdp_rdp_process_data_font(xrdp_rdp.c:1310)] yeah, up_and_running
[2024-06-05T09:53:24.693+0100] [INFO ] [xrdp_bitmap_create(xrdp_bitmap_common.c:102)] xrdp_bitmap_create: noorders
[2024-06-05T09:53:24.729+0100] [INFO ] [xrdp_mm_create(xrdp_mm.c:60)] xrdp_mm_create: bpp 32 mcs_connection_type 7 jpeg_codec_id 0 v3_codec_id 0 rfx_codec_id 0 h264_codec_id 0
[2024-06-05T09:53:24.759+0100] [INFO ] [km_load_file(lang.c:290)] Loading keymap file /etc/xrdp/km-00000809.ini
[2024-06-05T09:53:24.787+0100] [WARN ] [get_keymaps(lang.c:269)] local keymap file for 0x00000809 found and doesn't match built in keymap, using local keymap file
[2024-06-05T09:53:24.818+0100] [INFO ] [xrdp_channel_drdynvc_start(xrdp_channel.c:756)] xrdp_channel_drdynvc_start: drdynvc_channel_id -1
[2024-06-05T09:53:24.852+0100] [INFO ] [xrdp_login_wnd_get_monitor_dpi(xrdp_login_wnd.c:736)] Login screen monitor height is 1080 pixels over 607 mm (45 DPI)
[2024-06-05T09:53:24.910+0100] [INFO ] [egfx_initialize(xrdp_mm.c:1500)] egfx_initialize: gfx capable client
[2024-06-05T09:53:24.944+0100] [INFO ] [xrdp_egfx_create(xrdp_egfx.c:1075)] xrdp_egfx_create: error 0 channel_id 1
[2024-06-05T09:53:24.995+0100] [INFO ] [xrdp_mm_egfx_caps_advertise(xrdp_mm.c:1281)] xrdp_mm_egfx_caps_advertise:
[2024-06-05T09:53:25.298+0100] [INFO ] [xrdp_mm_egfx_caps_advertise(xrdp_mm.c:1308)]   version 0x00080004 flags 0x00000000 (index: 0)
[2024-06-05T09:53:25.633+0100] [INFO ] [xrdp_mm_egfx_caps_advertise(xrdp_mm.c:1308)]   version 0x00080105 flags 0x00000000 (index: 1)
[2024-06-05T09:53:25.966+0100] [INFO ] [xrdp_mm_egfx_caps_advertise(xrdp_mm.c:1308)]   version 0x000a0002 flags 0x00000000 (index: 2)
[2024-06-05T09:53:25.136+0100] [INFO ] [xrdp_mm_egfx_caps_advertise(xrdp_mm.c:1308)]   version 0x000a0200 flags 0x00000000 (index: 3)
[2024-06-05T09:53:25.171+0100] [INFO ] [xrdp_mm_egfx_caps_advertise(xrdp_mm.c:1308)]   version 0x000a0301 flags 0x00000000 (index: 4)
[2024-06-05T09:53:25.205+0100] [INFO ] [xrdp_mm_egfx_caps_advertise(xrdp_mm.c:1308)]   version 0x000a0400 flags 0x00000000 (index: 5)
[2024-06-05T09:53:25.238+0100] [INFO ] [xrdp_mm_egfx_caps_advertise(xrdp_mm.c:1308)]   version 0x000a0502 flags 0x00000000 (index: 6)
[2024-06-05T09:53:25.272+0100] [INFO ] [xrdp_mm_egfx_caps_advertise(xrdp_mm.c:1308)]   version 0x000a0600 flags 0x00000000 (index: 7)
[2024-06-05T09:53:25.306+0100] [INFO ] [xrdp_mm_egfx_caps_advertise(xrdp_mm.c:1308)]   version 0x000a0701 flags 0x00000000 (index: 8)
[2024-06-05T09:53:25.339+0100] [INFO ] [xrdp_mm_egfx_caps_advertise(xrdp_mm.c:1363)]   replying version 0x000a0701 flags 0x00000000
[2024-06-05T09:53:25.372+0100] [INFO ] [xrdp_mm_egfx_caps_advertise(xrdp_mm.c:1368)] xrdp_mm_egfx_caps_advertise: xrdp_egfx_send_capsconfirm error 0 best_index 8
[2024-06-05T09:53:25.406+0100] [INFO ] [xrdp_egfx_reset_graphics(xrdp_egfx.c:675)] xrdp_egfx_reset_graphics:
[2024-06-05T09:53:25.439+0100] [INFO ] [xrdp_egfx_reset_graphics(xrdp_egfx.c:726)] xrdp_egfx_reset_graphics: (index 0) monitor left 0 top 0 right 1919 bottom 1079 is_primary 1
[2024-06-05T09:53:25.473+0100] [INFO ] [xrdp_egfx_reset_graphics(xrdp_egfx.c:726)] xrdp_egfx_reset_graphics: (index 1) monitor left 1920 top 0 right 3839 bottom 1079 is_primary 0
[2024-06-05T09:53:25.506+0100] [INFO ] [xrdp_egfx_reset_graphics(xrdp_egfx.c:733)] xrdp_egfx_reset_graphics: width 3840 height 1080 monitorcount 2
[2024-06-05T09:53:25.540+0100] [INFO ] [xrdp_mm_egfx_caps_advertise(xrdp_mm.c:1374)] xrdp_mm_egfx_caps_advertise: xrdp_egfx_send_reset_graphics error 0 monitorCount 2
[2024-06-05T09:53:25.573+0100] [INFO ] [xrdp_mm_egfx_create_surfaces(xrdp_mm.c:1228)] xrdp_mm_egfx_create_surfaces: monitor count 2
[2024-06-05T09:53:25.607+0100] [INFO ] [xrdp_mm_egfx_create_surfaces(xrdp_mm.c:1258)] xrdp_mm_egfx_create_surfaces: map surface_id 0 left 0 top 0 width 1920 height 1080
[2024-06-05T09:53:25.640+0100] [INFO ] [xrdp_mm_egfx_create_surfaces(xrdp_mm.c:1258)] xrdp_mm_egfx_create_surfaces: map surface_id 1 left 1920 top 0 width 1920 height 1080
[2024-06-05T09:53:25.673+0100] [INFO ] [xrdp_encoder_create(xrdp_encoder.c:145)] xrdp_encoder_create: starting gfx rfx pro codec session
[2024-06-05T09:53:25.707+0100] [INFO ] [xrdp_encoder_create(xrdp_encoder.c:184)] init_xrdp_encoder: initializing encoder codec_id 0
[2024-06-05T09:53:25.741+0100] [INFO ] [xrdp_encoder_create(xrdp_encoder.c:241)] Using 3145728 max_compressed_bytes for encoder
[2024-06-05T09:53:25.774+0100] [INFO ] [xrdp_mm_egfx_invalidate_wm_screen(xrdp_mm.c:1102)] xrdp_mm_egfx_invalidate_wm_screen:
[2024-06-05T09:53:25.774+0100] [INFO ] [proc_enc_msg(xrdp_encoder.c:1109)] proc_enc_msg: thread is running
[2024-06-05T09:53:25.807+0100] [INFO ] [xrdp_mm_egfx_caps_advertise(xrdp_mm.c:1387)] xrdp_mm_egfx_caps_advertise: egfx created.

Windows 11 Display settings:-

image

Windows 10

image

image

@derekschrock - can you provide an RDP config, and maybe a connection log? There's clearly some difference here which we're not picking up on. I'm pretty sure it's client-side, as the client will be the one to initiate the resize.

derekschrock commented 5 months ago

At least with Windows 10 some extra testing seems to show this depends on the primary display setting. Can you try with setting the right display as primary?

With the a 1x2 if the right display is the primary going from fullscreen all displays, windowed, maximize will full screen only on the right displays. Setting the left display as primary you get the expected windowed to fullscreen resize with 32 bit.

My RDP config is:

screen mode id:i:2
use multimon:i:1
desktopwidth:i:1920
desktopheight:i:1080
session bpp:i:32
winposstr:s:0,1,234,60,1690,999
compression:i:1
keyboardhook:i:2
audiocapturemode:i:0
videoplaybackmode:i:1
connection type:i:6
networkautodetect:i:0
bandwidthautodetect:i:1
displayconnectionbar:i:1
enableworkspacereconnect:i:0
disable wallpaper:i:0
allow font smoothing:i:1
allow desktop composition:i:1
disable full window drag:i:0
disable menu anims:i:0
disable themes:i:0
disable cursor setting:i:0
bitmapcachepersistenable:i:1
audiomode:i:2
redirectprinters:i:1
redirectcomports:i:0
redirectsmartcards:i:1
redirectclipboard:i:1
redirectposdevices:i:0
autoreconnection enabled:i:1
authentication level:i:2
prompt for credentials:i:1
negotiate security layer:i:1
remoteapplicationmode:i:0
alternate shell:s:
shell working directory:s:
gatewayhostname:s:
gatewayusagemethod:i:4
gatewaycredentialssource:i:4
gatewayprofileusagemethod:i:0
promptcredentialonce:i:0
gatewaybrokeringtype:i:0
use redirection server name:i:0
rdgiskdcproxy:i:0
kdcproxyname:s:
drivestoredirect:s:C:\;
redirectwebauthn:i:1
enablerdsaadauth:i:0
derekschrock commented 5 months ago

Playing around with more displays on Windows 10:

rowlap commented 5 months ago

I tried the exact same steps on Windows 11 mstsc client against xrdp 0.9.25 vs 0.10, on a 4-screen setup. It's not necessary to log in or interact with the user/password prompt at all, presumably ruling out anything related to the user / Xorg backend / sesman.

What's different in the xrdp log output? Only in 0.9.25:

[20240605-09:27:51] [DEBUG] Client monitor [0]: left= 3840, top= 0, right= 7679, bottom= 2159, is_primary?= 0
[20240605-09:27:51] [DEBUG] Client monitor [1]: left= 0, top= -2160, right= 3839, bottom= -1, is_primary?= 0
[20240605-09:27:51] [DEBUG] Client monitor [2]: left= 3840, top= -2160, right= 7679, bottom= -1, is_primary?= 0
[20240605-09:27:51] [DEBUG] Client monitor [3]: left= 0, top= 0, right= 3839, bottom= 2159, is_primary?= 1
...
[20240605-09:27:51] [WARN ] Received [MS-RDPBCGR] TS_UD_HEADER type 0xc008 is unknown (ignored)
...
[20240605-09:27:51] [INFO ] xrdp_mm_create: bpp 24 mcs_connection_type 7 jpeg_codec_id 0 v3_codec_id 0 rfx_codec_id 0 h264_codec_id 0

Only in 0.10:

[2024-06-05T09:29:21.942-0400] [INFO ] client supports gfx protocol
[2024-06-05T09:29:21.943-0400] [WARN ] Physical desktop dimensions (0x0) are invalid
...
[2024-06-05T09:29:21.948-0400] [DEBUG] libxrdp_process_monitor_stream: The number of monitors received is: 4
...
[2024-06-05T09:29:21.949-0400] [DEBUG] libxrdp_process_monitor_ex_stream: The number of monitors received is: 4
...
[2024-06-05T09:29:22.699-0400] [INFO ] Client supports multi-screen resizes by xrdp
...
[2024-06-05T09:29:22.701-0400] [INFO ] Client Capability: LARGE_POINTER_FLAG_96x96 supported
...
[2024-06-05T09:29:22.735-0400] [INFO ] Login screen monitor height is 2160 pixels over 349 mm (157 DPI)
[2024-06-05T09:29:22.737-0400] [DEBUG] Login screen scale factor 1.750000
...
[2024-06-05T09:29:22.766-0400] [DEBUG] Login state has changed to WMLS_USER_PROMPT
[2024-06-05T09:29:22.872-0400] [INFO ] xrdp_egfx_create: error 0 channel_id 1
[2024-06-05T09:29:23.157-0400] [INFO ] xrdp_mm_egfx_caps_advertise:
[2024-06-05T09:29:23.157-0400] [INFO ]   version 0x00080004 flags 0x00000000 (index: 0)
[2024-06-05T09:29:23.158-0400] [INFO ]   version 0x00080105 flags 0x00000000 (index: 1)
[2024-06-05T09:29:23.158-0400] [INFO ]   version 0x000a0002 flags 0x00000000 (index: 2)
[2024-06-05T09:29:23.159-0400] [INFO ]   version 0x000a0200 flags 0x00000000 (index: 3)
[2024-06-05T09:29:23.159-0400] [INFO ]   version 0x000a0301 flags 0x00000000 (index: 4)
[2024-06-05T09:29:23.160-0400] [INFO ]   version 0x000a0400 flags 0x00000000 (index: 5)
[2024-06-05T09:29:23.160-0400] [INFO ]   version 0x000a0502 flags 0x00000000 (index: 6)
[2024-06-05T09:29:23.160-0400] [INFO ]   version 0x000a0600 flags 0x00000000 (index: 7)
[2024-06-05T09:29:23.161-0400] [INFO ]   version 0x000a0701 flags 0x00000000 (index: 8)
[2024-06-05T09:29:23.161-0400] [INFO ]   replying version 0x000a0701 flags 0x00000000
[2024-06-05T09:29:23.162-0400] [DEBUG] xrdp_egfx_send_capsconfirm: xrdp_egfx_send_s error 0
[2024-06-05T09:29:23.162-0400] [INFO ] xrdp_mm_egfx_caps_advertise: xrdp_egfx_send_capsconfirm error 0 best_index 8
[2024-06-05T09:29:23.163-0400] [INFO ] xrdp_egfx_reset_graphics:
[2024-06-05T09:29:23.163-0400] [INFO ] xrdp_egfx_reset_graphics: (index 0) monitor left 3840 top 2160 right 7679 bottom 4319 is_primary 0
[2024-06-05T09:29:23.164-0400] [INFO ] xrdp_egfx_reset_graphics: (index 1) monitor left 0 top 0 right 3839 bottom 2159 is_primary 0
[2024-06-05T09:29:23.164-0400] [INFO ] xrdp_egfx_reset_graphics: (index 2) monitor left 3840 top 0 right 7679 bottom 2159 is_primary 0
[2024-06-05T09:29:23.165-0400] [INFO ] xrdp_egfx_reset_graphics: (index 3) monitor left 0 top 2160 right 3839 bottom 4319 is_primary 1
[2024-06-05T09:29:23.165-0400] [INFO ] xrdp_egfx_reset_graphics: width 7680 height 4320 monitorcount 4
[2024-06-05T09:29:23.166-0400] [DEBUG] xrdp_egfx_send_reset_graphics: xrdp_egfx_send_s error 0
[2024-06-05T09:29:23.166-0400] [INFO ] xrdp_mm_egfx_caps_advertise: xrdp_egfx_send_reset_graphics error 0 monitorCount 4
[2024-06-05T09:29:23.166-0400] [DEBUG] xrdp_egfx_send_map_surface: xrdp_egfx_send_s error 0
[2024-06-05T09:29:23.167-0400] [INFO ] xrdp_mm_egfx_create_surfaces: map surface_id 0 left 3840 top 2160 width 3840 height 2160
[2024-06-05T09:29:23.167-0400] [DEBUG] xrdp_egfx_send_map_surface: xrdp_egfx_send_s error 0
[2024-06-05T09:29:23.168-0400] [INFO ] xrdp_mm_egfx_create_surfaces: map surface_id 1 left 0 top 0 width 3840 height 2160
[2024-06-05T09:29:23.168-0400] [DEBUG] xrdp_egfx_send_map_surface: xrdp_egfx_send_s error 0
[2024-06-05T09:29:23.169-0400] [INFO ] xrdp_mm_egfx_create_surfaces: map surface_id 2 left 3840 top 0 width 3840 height 2160
[2024-06-05T09:29:23.169-0400] [DEBUG] xrdp_egfx_send_map_surface: xrdp_egfx_send_s error 0
[2024-06-05T09:29:23.170-0400] [INFO ] xrdp_mm_egfx_create_surfaces: map surface_id 3 left 0 top 2160 width 3840 height 2160
[2024-06-05T09:29:23.170-0400] [INFO ] xrdp_encoder_create: starting gfx rfx pro codec session
[2024-06-05T09:29:23.171-0400] [INFO ] xrdp_mm_egfx_invalidate_wm_screen:
[2024-06-05T09:29:23.171-0400] [INFO ] xrdp_mm_egfx_caps_advertise: egfx created.
[2024-06-05T09:29:23.476-0400] [DEBUG] xrdp_egfx_process: unknown cmdId 0x10

It's worth noting in both cases, there is no log output created at all from the client window manipulation. I can't say with any certainty whether xrdp even knows when the window is restored / maximized, but it's not logged at DEBUG level.

In the 0.10 case, the window would not maximize back to full screen across 4 monitors, but only 2 of the screens, at which point the login prompt was invisible / rendered elsewhere.

matt335672 commented 5 months ago

Thanks both - that's great work.

I should be able to reproduce this based on the information you've both provided. I'll have a go and report back.

The codepaths for GFX are fairly different from the other codepaths, as Microsoft decided to implement it over a different virtual channel. From what Derek has said, selecting 24-bit colour should result in the same behaviour as xrdp v0.9.x.

At this stage, the only analysis I can provide is based on this interesting statement from @rowlap which is in agreement with my own observations:-

It's worth noting in both cases, there is no log output created at all from the client window manipulation. I can't say with any certainty whether xrdp even knows when the window is restored / maximized, but it's not logged at DEBUG level.

You'd certainly get something relating to a client window resize event at DEBUG level. So one of the following would seem to be the case:- 1) Client bug. This can be ruled out by testing Windows to Windows. I don't think this is likely. 2) We're not sending the client some information it needs regarding the Windows layout (possible, but the layout came from the client in the first place!) 3) Something else we're sending the client is confusing it.

Either 2) or 3) above might take a while to track down.

Please tell me if I've missed anything obvious.

matt335672 commented 5 months ago

I can reproduce this now.

Running the following:- 1) Windows 10 22H2 client 10.0.19041.4355 2) the latest devel version of XRDP @8048a63b49239840cd30323ad2dbd8fc18f7437b 3) , and with two1920x1080 monitors, and the primary on the right

I see the following:- 1) xrdp GFX minimise/maximise results in a misplaced Window exactly as described by @derekschrock in this comment 2) xrdp non-GFX minimise-maximise is fine 3) Windows to Windows minimise-maximise is fine. I'm assuming this is using GFX.

As @rowlap mentions, this is all doable on the login screen, so we can rule out xorgxrdp, the X server and anything related to the session.

Thanks again both. It might take a while to track down a solution but you've really helped above.

matt335672 commented 5 months ago

I'm adding some notes here, as I've got a busy weekend IRL and I may not get to look at this until next week.

There seem to be three places where the monitor geometry is sent to the client:- 1) In the optional Monitor layout PDU during a capabilities exchange 2) [GFX only] In the RDPGFX_RESET_GRAPHICS_PDU 3) [GFX only] in the RDPGFX_MAP_SURFACE_TO_OUTPUT_PDU

The first of these seems to be exactly as specified in [MS-RDPBCGR] 2.2.12.1, both for GFX and non-GFX connections. When I get a chance I'll check out the other two.

matt335672 commented 4 months ago

I think our implementation of RDPGFX_RESET_GRAPHICS_PDU is incorrect.

@pancro, @derekschrock, @rowlap - please try #3111 if you have the time. It's a tiny change, but will need a lot of testing!

derekschrock commented 4 months ago

Looks good. Tested #3111 applied to 6fa941e208 with a 1x2, 1x3, a pyramid (1x2 with one above middle), and L (1x2 with one above left most) all with right most or bottom right as the primary. Windowing/Restoring worked as expected. (fyi you can use cnt-alt-break to quickly window/restore).

pancro commented 4 months ago

@matt335672, #3111 looks good here as well. I tried 2 adjacent monitors (primary one being on the right) and 3 monitors in inverted pyramid shape (2 monitors on top, on montor in the centre below, primary monitor being the bottom one)

rowlap commented 4 months ago

Works for me. Tested a 2-screen sideways "T" layout, and a regular 2x2 with main display in the bottom left. Before the patch, both fail on maximise. After, both work as expected.

Nexarian commented 4 months ago

To be honest, I didn't really think hard about which of those two arrays to use when I wrote this originally. It is very possible that this is the correct way. I agree extensive testing is needed though.