Skip to content

Instantly share code, notes, and snippets.

@generic-internet-user
Last active January 25, 2025 18:48
Show Gist options
  • Save generic-internet-user/4a2783cd6a7f5c554e66e6ac30c417c9 to your computer and use it in GitHub Desktop.
Save generic-internet-user/4a2783cd6a7f5c554e66e6ac30c417c9 to your computer and use it in GitHub Desktop.

Wayland Cursor Lag: Arch Install Process

NOTE: I am only putting this online because I didn't feel like re-describing the entire thing again. Also, please note that this was written as I went and some parts (the "configure Xorg" part at the bottom) were not finished (only the intel part is there, not the amdgpu or nvidia ones; and before anybody asks, yes I did in fact give up testing all of this at the AMD part for which the instructions aren't here because I didn't feel like putting them here)

Self-explanatory; this is an outline of the process used to install Arch for the purposes of this project.

Before installation

Download Arch

This part is implied anyway, but in any case, download the Arch ISO, checksum it afterwards, and then proceed to put it onto a bootable medium of some kind (ventoy or another multiboot ISO solution is preferred for this, I am not going back to dding entire 32GB SD cards to boot into a single distro image)

Set up the drive

Get an SSD (in this case, 256 GB is enough) and partition it something like this (substitute sdb for whatever the drive actually gets enumerated as):

sdb        256GB
├─sdb1     512MB # EFI partition
├─sdb2     4GB   # swapspace (bare, not LUKS because we don't need that here (tho I do it on all actually "legit" setups))
├─sdb3    ~83GB  # gtx970 btrfs root
├─sdb4    ~83GB  # a285 btrfs root
└─sdb5    ~83GB  # t480 btrfs root

sdb1 and sdb2 to have the EFI system (fdisk 1) and BIOS boot (fdisk 4) types set, respectively, everything else to stay as default

mkfs.btrfs all partitions meant to be btrfs (again, change the drive name as to not wipe out the wrong thing(s)):

for i in {4..7}; do
    sudo mkfs.btrfs "/dev/sdb$i"
done

Format the EFI partition as fat32:

mkfs.vfat -F 32 /dev/sdb1

Machine-specific requirements and quirks

T480: install and enable throttled because of the throttling issue that these things suffer from, otherwise nothing specific A285: is the only AMD CPU machine being tested so amd-ucode and vulkan-radeon instead of intel-ucode and vulkan-intel respectively, and don't bother with xf86-video-intel-git i7-4770S (GTX 970 dGPU): has an nvidia card so install nvidia-dkms, nvidia-utils and nvidia-settings

Actually installing it

Boot and connect to WiFi

(yes, I know that you should do this over wired but I don't quite have that accessible at all times, I mean I do have powerline but why even bother at that point)

## Set font
setfont sun12x22 # I like this one, no comment

## Connect to network
iwctl station wlan0 scan on
iwctl station wlan0 connect my-ssid
[enter password]
ping archlinux.org

Enable parallel downloading in pacman.conf

Open /etc/pacman.conf (in the arch live environment), uncomment the testing repos, and uncomment ParallelDownloads; the default of 5 is actually (mostly) perfect (for me) so we'll leave it as-is.

Mount everything

mount /dev/sdXX /mnt
btrfs su cr /mnt/@
btrfs su cr /mnt/@home
btrfs su cr /mnt/@log
btrfs su cr /mnt/@cache
umount /mnt
mount -o defaults,noatime,ssd,space_cache=v2,autodefrag,subvol=/@ /dev/sdXX /mnt # Not enabling compression here in order to minimize (comparatively minimal, but still) CPU load 
mkdir /mnt/home
mkdir -p /mnt/boot/efi # Yes, I am indeed using the "not recommended anymore" mountpoint for the ESP, I don't care, it still works, Ubuntu and Debian still use it so I get to have it in my muscle memory for chrooting into (my, at least) broken systems when they're fucked up, regardless of distro, and if anything starts being unhappy with it *then* I'll switch to `/efi` or `/boot` (for sd-boot only) or whatever systemd/Red Hat/Big Blue wants you to use nowadays
mkdir -p /mnt/var/log
mkdir /mnt/var/cache
mount -o defaults,noatime,ssd,space_cache=v2,autodefrag,subvol=/@home /dev/sdXX /mnt/home
mount -o defaults,noatime,ssd,space_cache=v2,autodefrag,subvol=/@log /dev/sdXX /mnt/var/log
mount -o defaults,noatime,ssd,space_cache=v2,autodefrag,subvol=/@cache /dev/sdXX /mnt/var/cache
mount -o defaults,noatime,umask=0077,discard /dev/sdX1 /mnt/boot/efi
# Label it while we're at it
swapon /dev/sdX2
btrfs fi label /mnt MACHINE_NAME

Install the repo packages (all machines)

pacstrap -K /mnt \
    `# kernel and base   ` linux-zen linux-firmware sof-firmware base \
    `# other kernel stuff` dkms linux-zen-headers intel-ucode \
    `# build/download    ` base-devel git curl wget aria2 \
    `# KDE               ` plasma-meta kate konsole dolphin sddm \
    `# GNOME             ` gnome \
    `# certain GPU stuff ` vulkan-intel vulkan-validation-layers libva-utils mesa-utils \
    `# Xorg              ` xorg-server xorg-xrandr xorg-xdpyinfo xorg-xinit xorg-xauth openbox \
    `# boot              ` grub efibootmgr kbd \
    `# filesystems       ` btrfs-progs xfsprogs dosfstools udftools \
    `# other             ` networkmanager vim sudo picom lvm2 cryptsetup mako alacritty foot kitty nwg-look firefox openssh usbutils bash-completion man-pages man-db

Note the lack of certain essential (for a desktop/laptop that's meant to be daily driven, and to me, anyway) packages like flatpak, bluetooth stuff, a sound server (though the gnome package pulls in all of pipewire regardless) libreoffice, etc. Most of that stuff would be bloat here (technically even firefox is bloat for this setup but I want there to be a web browser for when it's necessary)

Get in

The first things

genfstab -U /mnt >> /etc/fstab 
arch-chroot /mnt
sed -i 's/#en_US.UTF-8/en_US.UTF-8/' /etc/locale.gen # why edit it manually when `sed` works well enough?
echo 'LANG=en_US.UTF-8' >| /etc/locale.conf
locale-gen
ln -sf /usr/share/zoneinfo/???/??? /etc/localtime
hwclock --systohc
echo 'MACHINE-NAMEtestrig' >| /etc/hostname

Enable testing repos

https://wiki.archlinux.org/title/Official_repositories Also, enable KDE and GNOME testing repos: https://wiki.archlinux.org/title/Official_repositories#gnome-unstable https://wiki.archlinux.org/title/Official_repositories#kde-unstable

Do NOT enable multilib and multilib-testing, because why would I here, not really needed here.

Enable parallel downloads while you're at it too.

And upgrade:

pacman -Syu

Wanted to do it at the beginning (install testing packages during pacstrap) and did it that way on the T480 but that resulted in a marginal amount of breakage (most notably, the polkitd user wasn't there in /etc/passwd and I had to add one manually), so it's probably a better idea to install with main repo packages first and upgrade to testing ones later.

Initramfs stuff

Switch to a systemd-based initramfs for... some reason:

# before
HOOKS=(base udev autodetect microcode modconf kms keyboard keymap consolefont block filesystems fsck)

# after
HOOKS=(base systemd autodetect microcode modconf kms keyboard sd-vconsole block filesystems fsck)

Regenerate it:

# why not
printf 'KEYMAP=us\nFONT=sun12x22` >| /etc/vconsole.conf
mkinitcpio -P

Not adding the nvidia modules for that one machine because, apparently, that technically doesn't need to be done anymore.

Enable networkmanager and SDDM

(Note: We aren't enabling rootless Xorg in SDDM here to rule everything out)

systemctl enable NetworkManager.service
systemctl disable NetworkManager-wait-online.service
systemctl enable sddm.service

Add users

Technically the "standalone" WMs shouldn't even need separate users but... plausible deniability reduction. So we're creating them anyway.

for user in {kde-user,gnome-user,sway-user,wayfire-user,hyprland-user,nodesktop-user}; do
    useradd "$user"
    usermod -aG wheel "$user"
    mkdir "/home/$user"
    chown "$user":"$user" "/home/$user"
    echo "Setting password for $user"
    passwd "$user"
done

password, admin or something equally simplistic/obvious is fine for the passwords here, as it's a single use affair anyway.

Enable wheel group for sudo

EDITOR=/usr/bin/vim visudo # You probably already know what to do here

Install GRUB

# /etc/default/grub: should be fine as-is?...
grub-install --target=x86_64-efi --bootloader-id="Arch Linux (MACHINE_NAME Test Rig) --efi-directory=/boot/efi # Maybe I should export $MACHINE_NAME as a variable... nah, not really needed here
grub-mkconfig -o /boot/grub/grub.cfg # I keep forgetting to do this and then have to chroot back in and actually do it

Set root password

passwd root # Technically, just `passwd` is fine because you're already root

Reboot

exit
umount -R /mnt
reboot

Post-install

Connect to network

nmtui is good enough for this.

Install paru

Log in as nodesktop-user and do git clone https://aur.archlinux.org/paru-bin.git, then cd paru-bin and makepkg -sic.

Enable multithreaded compile

Open /etc/makepkg.conf, then find the line with MAKEFLAGS= on it, uncomment it, and change -j2 to -j8 (all machines involved are various kinds of 4 core, 8 threads types of deals, so that's the case for all of them)

On first machine

Install everything to be built from source

paru -Syu \
    `# Hyprland     ` hyprland-git \
    `# Sway         ` wlroots-git sway-git swaylock-git swayidle-git swaybg-git \
paru -R sway-git wlroots-git
paru -Syu \
    `# Wayfire      ` wayfire-git wf-shell-git wcm-git

# Copy the packages for Wayfire and Sway out of paru cache
mkdir -p ~/packages/wayfire
mkdir ~/packages/sway
cp ~/.cache/paru/clone/{wayfire,wf-shell,wcm}-git/*.pkg.tar.zst ~/packages/wayfire/
cp ~/.cache/paru/clonw/{wlroots,sway}-git/*.pkg.tar.zst ~/packages/sway/

# Switch between Wayfire and Sway like this:
paru -R wayfire-git wf-shell-git wcm-git
pacman -U ~/packages/sway/*.pkg.tar.zst

# (or vice versa)

Install source versions of repo packages which are to be swapped in and out

These will be built and then replaced with the repo versions immediately afterwards, with the intent being to swap them back in whenever I'm testing those ones specifically. These packages are mutter-beta-performance, gnome-shell-beta-performance (Not testing the patched gnome packages anymore, not really worth the effort), and xf86-video-intel-git (but only on the T480); the former two are relatively straightforward, the latter this has some weirdness involved but isn't too hard either. Also, Wayfire cannot coexist with Sway because wayfire-git ends up shipping its own copy of wlroots (this actually results in wayfire-git failing to install without you removing the wlroots package beforehand because it just so happens to pull it in as a build dependency for something else, so you need to build wayfire, then remove wlroots, actually install it, then let wf-shell and wcm build and install) and this conflicts with the wlroots-git package that sway-git depends on, so these will need to be swapped in and out as well.

xf86-video-intel
git clone https://aur.archlinux.org/xf86-video-intel-git.git
cd xf86-video-intel-git
vim PKGBUILD
# change this:
#  export CFLAGS=${CFLAGS/-fno-plt}
#  export CXXFLAGS=${CXXFLAGS/-fno-plt}
#  export LDFLAGS=${LDFLAGS/,-z,now}
# to this (define build flags as empty):
#  export CFLAGS=""
#  export CXXFLAGS=""
#  export LDFLAGS=""
# THIS IS NOT A GOOD IDEA AT ALL!!! but it won't build otherwise (/etc/makepkg.conf has flags that conflict with it, and the ones defined in the PKGBUILD are supposed to resolve that but they don't work anymore but I'm not willing to dig into it and find a set of flags that works)
makepkg -sic

On all other machines

Just copy the paru cache and the things we built externally from the first machine's partition to the current filesystem. No need to build them over and over again, I guess.

Configure the desktops

Environment variables list

KWin Wayland: Legacy modesetting: KWIN_DRM_NO_AMS=1 Software cursors: KWIN_FORCE_SW_CURSOR=1

GNOME/Mutter: (might be outdated!) Legacy modesetting: MUTTER_DEBUG_FORCE_KMS_MODE=simple Software cursors: MUTTER_DEBUG_DISABLE_HW_CURSORS=1

wlroots: Legacy modesetting: WLR_DRM_NO_ATOMIC=1 Software cursors: WLR_NO_HARDWARE_CURSORS=1

Hyprland: Legacy modesetting: AQ_NO_ATOMIC=1 Software cursors: not an environment variable, but a config option: https://wiki.hyprland.org/Configuring/Variables/#cursor

Configure Hyprland

Log in as hyprland-user and start Hyprland (through SDDM should be fine) and have it generate its config, comment out the autogenerated line at the top, then set the libinput flat mouse acceleration profile (see this).

Also add the options for disabling hardware cursors and atomic modesetting, then comment them out and uncomment/recomment them as needed during testing.

Configure Sway

Add the variables for atomic KMS and HW cursors to /etc/environment, then comment them out. Mouse acceleration should be disable-able like this, or maybe that.

Configure Wayfire

Should take the same environment variables as Sway, mouse accel should be configurable in WCM but I'll find out once I actually do this.

Configure KDE

Log in as the correct user, then disable mouse acceleration in the settings app of theirs and then add the appropriate envvars for atomic and SW cursors to /etc/environment, commented out for switching purposes.

Configure GNOME

It's GNOME so it should be safely contained away from any other desktop's (especially KDE's) configs, so make sure to login as the correct user, and, also because it's GNOME, disabling mouse acceleration (the flat accel profile at least) requires dconf-editor, like this. Also add environment variables for the same things as above and comment them out.

Configure Xorg

On Intel, do something like this:

# Intel: /etc/X11/xorg.conf.d/20-intel.conf
Section "Device"
  Identifier "Intel Graphics"
  Driver "intel"
  Option "AccelMethod" "sna"
  Option "DRI" "iris"
  Option "VSync" "true"
  Option "TearFree" "true"
  Option "TripleBuffer" "true"
  Option "SwapbuffersWait" "true"

#  Driver "modesetting"
#  Option "VSync" "true"
#  Option "DRI" "iris"
EndSection

this is one of the parts I said was unfinished, and it shows

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment