Mawoka's Blog - Wayland with Nvidia on Manjaro KDE

Wayland with Nvidia on Manjaro KDE

04 December 2022

Wayland on Manjaro KDE

Intro

So I installed Wayland on my PC and I'll tell you my journey!

Why?

I got a 4k monitor and now I have a dual-monitor setup with a 4k monitor and a 1080p monitor. The problem: The scaling. X.org doesn't allow per screen scaling, so everything on my 1080p monitor was good, but everything on the 4k monitor was way too small to be readable. Then I searched in the internet and found out that Wayland can do per monitor scaling so I read a bit more and the main things I found:

If you got a nvidia-gpu, don't use Wayland, it is just buggy!

Nvidia-gpus aren't ready for Wayland yet!

But I still did it and even got it! Now I am running Wayland and the per-monitor scaling works!

Should you do it?

Probably not unless you also have 2 monitors with different resolutions. If you just got one monitor or two monitors with the same resolution, it works great but I think it is not worth the work and the time. I mean if you want to support Wayland, do it!

What you'll do

You'll install some packages, enable a kernel flag and patch a custom qt-version. That's it.

Install packages

sudo pacman -Syuu && sudo pacman -S wayland plasma-wayland-session

If you log out now, you can select Wayland as your session, but it crashes immediately. To prevent this, add a new kernel-parameter

Add the kernel-parameter

open the /etc/default/grub-file, like this: sudo nano /etc/default/grub and find the following: GRUB_CMDLINE_LINUX_DEFAULT=. There should already be some parameters, but you should add one: nvidia-drm.modeset=1. For me, the line looks like this:

GRUB_CMDLINE_LINUX_DEFAULT="quiet apparmor=1 security=apparmor udev.log_priority=3 nvidia-drm.modeset=1"

Note: It doesn't have to look the same for you.

After that, run sudo grub-mkconfig -o /boot/grub/grub.cfg to update grub. Now you should reboot.

Install new qt-version

OUTDATED

This also doesn't seem to be required since the 13th September 2022, with qt5-wayland-version 5.15.5+kde+r38-3 and newer.

You should log out and select at the bottom left wayland as the session. You should see your desktop. If the taskbar is really slow (10-20s from click to action) you'll need a patched qt-version. It really isn't that difficult. You'll just need 2 files. The first is the PKGBUILD:

# Maintainer: Felix Yan <felixonmars@archlinux.org>
# Contributor: Andrea Scarpino <andrea@archlinux.org>

pkgname=qt5-wayland
#pkgver=5.15.2+kde+r54
_basever=5.15.3
pkgver=5.15.3+kde+r40
pkgrel=1
 _commit=118674630cdb5933e66a8b4415afe7c716ad4662
arch=('x86_64')
url='https://www.qt.io'
license=('GPL3' 'LGPL3' 'FDL' 'custom')
pkgdesc='Provides APIs for Wayland'
depends=('qt5-declarative' 'libxcomposite')
makedepends=('vulkan-headers' 'git')
groups=('qt' 'qt5')
_pkgfqn=${pkgname/5-/}
source=(git+https://invent.kde.org/qt/qt/$_pkgfqn#commit=$_commit patch2.diff)
sha256sums=('SKIP')
options=(debug)

pkgver() {
  cd $_pkgfqn
  echo "$_basever+kde+r"`git rev-list --count v$_basever-lts-lgpl..$_commit`
}

prepare() {
  mkdir -p build

  pwd
  cd $_pkgfqn
  patch --forward --ignore-whitespace --strip=1 -p1 --batch --input="${srcdir}/patch2.diff"
  cd ..
}

build() {
  cd build

  qmake ../${_pkgfqn}
  make
}

package() {
  cd build

  make INSTALL_ROOT="$pkgdir" install

  # Drop QMAKE_PRL_BUILD_DIR because reference the build dir
  find "$pkgdir/usr/lib" -type f -name '*.prl' \
    -exec sed -i -e '/^QMAKE_PRL_BUILD_DIR/d' {} \;

  install -d "$pkgdir"/usr/share/licenses
  ln -s /usr/share/licenses/qt5-base "$pkgdir"/usr/share/licenses/${pkgname}
}
sha256sums=('SKIP', 'SKIP')


and the second one is called pacth2.diff:

diff --git a/src/client/qwaylanddisplay.cpp b/src/client/qwaylanddisplay.cpp
index e1987742..d7a9f36e 100644
--- a/src/client/qwaylanddisplay.cpp
+++ b/src/client/qwaylanddisplay.cpp
@@ -420,6 +420,21 @@ void QWaylandDisplay::ensureScreen()
 // Called in main thread, either from queued signal or directly.
 void QWaylandDisplay::flushRequests()
 {
+    while (wl_display_prepare_read(mDisplay) != 0) {
+    wl_display_dispatch_pending(mDisplay);
+    }
+    wl_display_flush(mDisplay);
+    // then check if there are any new events waiting to be read
+    struct pollfd pfd;
+    pfd.fd = wl_display_get_fd(mDisplay);
+    pfd.events = POLLIN;
+    int ret = poll(&pfd, 1, 0);
+    if (ret > 0) {
+        // if yes, read them now
+        wl_display_read_events(mDisplay);
+    } else {
+        wl_display_cancel_read(mDisplay);
+    }
     m_eventThread->readAndDispatchEvents();
 }

You'll have to put them into the same directory and enter makepkg -g >> PKGBUILD to update the hashsums. After that, install the dependencies by entering and build the package: makepkg -s. Now install the package created: sudo pacman -U qt5-wayland-*.pkg.tar.zst. The last thing to do is to reboot. Now, I'd recommend adding the following line to your /etc/pacman.conf: IgnorePkg = qt5-wayland so pacman doesn't automatically install newer versions of this package. The "source" of the patch is here: https://codereview.qt-project.org/c/qt/qtwayland/+/373473 . You'll have to patch the qt5-wayland package always since I don't think this patch will ever be merged into master.

Conclusion

It's possible and fairly usable, but there are still many bugs, especially for me with my dual-screen HiDPI-setup and Electron-based applications. All in all, it's more usable than the x.org-thing without per-monitor scaling.

15 0