Wayland drm multimonitor layout#351
Conversation
The Wayland support comes from changing the way input and output works: 1. Screen output is captured via DRM (Direct Rendering Manager) 2. Keyboard/Mouse input is injected via libevdev Both of these methods are lower level than the previous X11 code, so they're actually capable of becoming full replacements for the X11 mechanisms, should we ever want to do that. I've tried to make the changes minimally invasive to the existing code, instead of a big refactor into X11 vs DRM code paths. Known issues: 1. Logging out back to the greeter breaks the screen scraping. This is fixable, just requires work to figure some things out. 2. Cursor state is not reflected in the screen output To get the greeter working will require some more surgery. I haven't figured out how all of that session stuff works yet, but it is possible. It's largely just an issue of the system getting confused between Wayland/X11 states. One quite simple solution could be that once we detect Wayland, we remain in that state for the duration of the process life. I'm not sure if people care about dynamic switching between X11 and Wayland during a single boot - and I suspect not, so I think this would be a simple and robust solution to get the greeter working. If cursor state is necessary, then I can look into that. It just hasn't felt like a priority. I don't consider this work 100% finished. We still need to get the greeter working, and more testing/feedback. But if possible, I'd like to get this on a public branch so that I can start getting feedback. This work is sponsored by touchsource.com
This fixes a warning on modern compilers
Previously, we only worked on eg Ubuntu 24.04, where they still shipped Xorg/X11. Without this change the agent does not advertise desktop capability, and the "Desktop" tab in MeshCentral is unavailable.
This prevents us from switching back to X11 mode if we connect at the greeter screen. We may still be able to simplify the wayland detection to just the seat0 read.
It was already in monitor-info.js
Aiming to find the reason why we're failing on i915
* The screen capture now resumes automatically after a blank screen * Fixed leaking of framebuffer handle * Fixed spurious noisy logs on nvidia capture due to changing handles
Unfortunately I haven't yet found a reliable universal way to detect display rotation on wayland, so I'm adding an env var override, eg For "portrait right": MESH_KVM_ROTATION=270 By setting MESH_KVM_ROTATION to anything besides zero, we force the treatment of the display as rotated by either 90,180,270 degrees. I split it into it's own .c file, because I forsee this getting a bit messy, having to support various compositors.
Add multi-output DRM capture support and compose active scanout buffers into a single logical desktop frame. When running under KWin, read the session's logical output geometry and apply it to the DRM outputs so capture and input coordinates follow the desktop monitor arrangement, including scaled displays. Also make verbose DRM/EGL diagnostics opt-in through MESH_KVM_DRM_DEBUG to avoid repeated framebuffer logging during normal agent operation.
…onitor-layout # Conflicts: # meshcore/KVM/Linux/linux_kvm.c
Make Wayland client support mandatory for Linux KVM builds so release and CI builds cannot silently omit the generic xdg-output monitor layout path. The DRM backend now includes wayland-client directly, and the makefile fails early when the wayland-client development package is unavailable. This keeps Wayland monitor positioning and scaling behavior consistent between build servers and deployed agents.
|
I changed the monitor layout path to prefer the Wayland xdg-output protocol instead of relying only on KWin support-info. The KWin path worked for KDE, but it made multi-monitor positioning/scaling KDE-specific. xdg-output is exposed by multiple Wayland compositors and provides the logical output position and scaled size we need to map DRM-captured frames into the same layout the desktop is using. KWin support-info is still kept as a fallback if xdg-output is unavailable or cannot match every DRM connector, so KDE keeps the working path while non-KDE Wayland sessions get a compositor-neutral layout path as well. |
…yland-drm-multimonitor-layout
|
Tested on Bazzite/Fedora with KDE Plasma Wayland and two DisplayPort monitors, including fractional scaling. PR #351 improves the important baseline issue for this setup: MeshAgent can run through the DRM/libevdev path instead of relying on Xwayland geometry. On my system the agent now starts with:
That fixed the major pointer-offset problem caused by Xwayland exposing a physical/scaled virtual layout that did not match KDE's logical Wayland layout. I also tested the MeshCentral multi-monitor selector goal: letting the server/viewer know this is a multi-monitor system so the user can choose all displays or one specific display. For that, I needed an additional local patch on top of PR #351:
With those changes, MeshCentral exposes the normal monitor choices and I can select all monitors or an individual monitor, with control working on the selected display. The key point: PR #351 fixed the Wayland/DRM coordinate path for this setup, but the extra local patch is what changed DRM mode from "single display 0" to the normal multi-monitor display-list behavior. |
Populate the existing monitor list from DRM/Wayland logical outputs and advertise the normal multi-monitor display list in DRM mode. Allow MNG_KVM_SET_DISPLAY to select all monitors or an individual monitor, crop DRM capture to the selected output, and keep evdev absolute input mapped against the full virtual desktop so pointer control remains correct across non-origin displays.
|
@msegec Thanks for testing this out and the detailed info on a way forward with the monitor selection. Those changes have been made and pushed. They appear to be working for me without any issues, I can select any of my 4 monitors or switch back to viewing all. Tbh I had no idea this functionality even existed, I had to hunt down the UI in mesh central for it haha. |
|
oh sorry my bad! can u fix conflict! i need to learn git properly at times! |
…yland-drm-multimonitor-layout
|
@si458 The merge conflict has been resolved |
|
@Rambomst unforutunately i still get this problem message when i click connect in the desktop tab |
Hi Simon, Can you elaborate if it is just this one Ubuntu machine or many, or any other specifiic conditions such as multiple session connections etc, as I have not tested that yet. I literally solved the issue for my use case on Bazzite (Fedora based) and have not really pushed it elsewhere yet, was hoping the community etc could find parts useful from it and expand until its stable for full release. Let me know if I can assist you in any way. Mark |
|
@msegec many ubuntu machines sadly, both VM and physicals. im happy for people to submit their PRs then i can piece them together haha |
|
@si458 oh that is quite funny, I have been kind of ignoring that problem for a while, and working around it with other 'things' but yes, I too have that issue - I will see what I can come up with... not much time at the moment, but hopefully by the weekend, if someone else does not. |
|
I'm on holidays and will be back next week, I will admit I didn't test this at all on Ubuntu, will give it a go when I get back and work through those issues if no one else has come up with a fix. |
Enable runtime loading of required libraries (libdrm, libEGL, and libGLESv2) using `dlopen` to allow the agent to function without a pre-installed GL/DRM stack. Refactor the makefile to remove hard library linking while retaining headers for build compatibility. Additionally, update Wayland integration to dynamically load libwayland-client and provide fallbacks for missing libraries.
|
@si458 @msegec I have pushed some changes that will hopefully resolve your issue. Fixed the "KVM child process has unexpectedly exited" error, it was a libjpeg version mismatch (built against jpeg8 headers but linked the v62 lib). The makefile now auto-selects the matching turbojpeg so plain builds work. Also switched the KVM graphics libs (libdrm/EGL/GLESv2/wayland) to load via dlopen instead of being hard-linked, so the agent still starts on hosts without them and KVM just disables itself when they're missing. |
Introduce logic to nudge sleeping displays (DPMS) awake during DRM desktop layout calculations and retry within a timeout. Enhance KVM pipe cleanup by canceling timers and broken-pipe handlers to prevent errors from delayed memory access. Define `KVM_DRM_DISPLAY_WAKE_TIMEOUT_MS` and implement `kvm_events_evdev_wake` for pointer-based wake functionality.
|
Two more Wayland/DRM KVM fixes. Made remote desktop wake the screens on connect. Before, connecting while they were asleep just failed, since there's no active scanout to capture, now it should nudge them awake through the virtual input device and retries for a few seconds instead of giving up. Also fixed a crash on reconnect where tearing down a session could free the KVM pipe while a delayed "child unexpectedly exited" message was still queued against it, so it fired on freed memory. Now it cancels that timer before freeing the pipe. |


This is an extension of #335.and Fixes Ylianst/MeshCentral#2719
What I have introduced on top of that PR:
Improve DRM Wayland KVM multi-monitor layout handling
Add multi-output DRM capture support and compose active scanout buffers
into a single logical desktop frame. When running under KWin, read the
session's logical output geometry and apply it to the DRM outputs so
capture and input coordinates follow the desktop monitor arrangement,
including scaled displays.
Also make verbose DRM/EGL diagnostics opt-in through MESH_KVM_DRM_DEBUG
to avoid repeated framebuffer logging during normal agent operation.
I also merged in the latest updated from
masterTested on:
EndevourOS with KDE Plasma - Local env
CatchyOS with KDE Plasma - Test VM
Disclaimer: I used an AI coding assistant during the development of these changes.