Fractional HiDPI may work better under Wayland - however if the applications you use works best under X11 vs Wayland then this guide may be for you!
(Also to note - I completely ignore the fractional scaling options in the Display menu because they do not work for my system.)
If you apply fractional HiDPI under X11 and suspend your laptop by closing your lid then you will quickly find out that Ubuntu Budgie 20.04 does not keep your xrandr scaling settings. This guide will fix that issue.
The issue appears to be caused by Mutter removing any fractional scaling that is being applied via xrandr. The reason(s) for this is unknown and may be an unintentional bug. There appears to be no method, that I found, that can remove this functionality so working around it is what this guide is all about.
Also this guide explains this type of solution perfectly, and that even Apple takes a similar approach to their scaling as well. They also indicate that scaling broke in Mutter as of 3.32.
https://wilfredwee.github.io/entry/how-to-xrandr
So here’s my setup - I have a cheap $150 used laptop that has a 13" screen, intel gpu, and 1920x1080 resolution. It’s wonderfully sharp, but also wonderfully tiny on Linux at this native resolution, so how do we fix this? Also can we make it similar to an Apple retina screen of 2880x1800 resolution that the MacBook Pro 15" has?
If you do the math and multiply 1920x1080 by 1.5 then you will get 2880x1620!
So to get straight into it you will need to scale your Budgie DE to 2x so that we can later scale that back down.
Scale Budgie Up 2x
gsettings set org.gnome.settings-daemon.plugins.xsettings overrides "[{'Gdk/WindowScalingFactor', <2>}]"
gsettings set org.gnome.desktop.interface scaling-factor 2
Scale Budgie back down to 1.5x
xrandr --output eDP-1 --scale 1.5x1.5
Everything should look perfectly sharp and better than ever, but everything is not perfect as you may soon find out. If you close your lid and come back you will find that you are scaled backup to 2x and the xrandr scaling has been wiped out. You will also find out that if you suspend manually before closing the lid then the scaling will not be lost - but that’s annoying you want to close your lid like a sane person, right?
The next steps are not for the faint of heart but it will get you where you want to to go. So lets layout what we want to do.
A.) Apply the scaling when you first login.
B.) Disable the normal lid close suspend
C.) Configure your custom lid close suspend, so you can re-apply scaling
D.) Optional Fix screen tearing for Intel GPUs
I will tell you right now that steps 1 & 2… they’re pretty easy step 3 is not. Why? What issues are you going to run into? Well it may vary with your GPU &/or driver but if your system is like mine you will have graphical glitches that will leave literal transparent holes in your windows after rescaling so we will need to clean that up.
Also to ensure that your custom suspend method is working we will play sounds to help you know that your laptop has indeed gone to sleep correctly. You can comment these out later if you would like once you are comfortable with the setup.
Let’s Begin
Section A.) Apply the scaling when you first login.
We will create 2 files to quickly get up and running.
1.) Get your connect display name (this may slightly change if you later add an xorg.conf file, so be prepared to possibly come back to this.)
xrandr | grep " connected " | awk '{ print$1 }'
My result was eDP-1, but later becomes eDP1 due ot my xorg.conf file for Intel - to try and lessen any tearing.
- Create directory for the scripts
mkdir ~/.config/scripts/
- Create the script
nano ~/.config/scripts/startup.sh
#!/bin/bash
until [ xrandr ]; do sleep 1; done
xrandr --output eDP1 --scale 1.5x1.5
chmod +x ~/.config/scripts/startup.sh
Optional - I also added the following to startup.sh as it resolves an issue that I have with my touchpad to make it more sensitive. (Also installed a synaptics driver)
synclient MinSpeed=1.8 MaxSpeed=4 AccelFactor=0.0997009
xinput set-prop 10 "Device Accel Velocity Scaling" 50
xinput set-prop 10 "Synaptics Coasting Speed" 30 50
- Create the desktop shortcut file in your autostart directory
nano ~/.config/autostart/startup.desktop
[Desktop Entry]
Name=Startup
GenericName=Path
Comment=Startup Patches
Exec=/bin/bash -c "/home/{username}/.config/scripts/startup.sh"
Terminal=false
Type=Application
X-GNOME-Autostart-enabled=true
This completes section A. Your resolution and other fixes ought to be applied on login.
Section B) Disable the normal lid close suspend
1.) Ignore Lid Close Events (by changing suspend to ignore)
sudo nano /etc/systemd/logind.conf
...
HandleLidSwitch=ignore
HandleLidSwitchExternalPower=ignore
HandleLidSwitchDocked=ignore
...
systemctl restart systemd-logind
Note: Only for testing you can also set IgnoreLid=false in /etc/UPower/UPower.conf to witness Mutter screwing up your scaling graphics on lid close events as it ignores these type of settings and does its own thing. service upower restart
Now you are ready for what was the longest and most difficult part of this tutorial to get right.
C.) Configure your custom lid close suspend, so you can re-apply scaling.
Note: This largely follows the advice here 18.04 - How to run a script when the lid is closed? - Ask Ubuntu .
We will create these 4 files
/etc/acpi/events/laptop-lid
/etc/acpi/laptop-lid.sh
~/.Xdbus
~/.config/scripts/monitor.sh
sudo nano /etc/acpi/events/laptop-lid
event=button/lid.*
action=/etc/acpi/laptop-lid.sh
update all {username} to simply your username (no brackets)
sudo nano /etc/acpi/laptop-lid.sh
#!/bin/bash
DISPLAY=:0
sleep 1
source /home/{username}/.Xdbus
grep -q closed /proc/acpi/button/lid/*/state
if [ $? = 0 ]
then
killall dbus-monitor
killall monitor.sh
# close action
aplay /usr/share/sounds/sound-icons/percussion-50.wav
su {username} -c "gnome-screensaver-command -l"
sleep 1
systemctl suspend
sleep 10
# You should not hear this 2nd noise on sleep, but only on resume!
aplay /usr/share/sounds/sound-icons/percussion-50.wav
else
su {username} -c "/usr/bin/bash -c '/home/{username}/.config/scripts/monitor.sh'" &
aplay /usr/share/sounds/sound-icons/piano-3.wav
fi
sudo chmod +x /etc/acpi/laptop-lid.sh
nano ~/.Xdbus
export XDG_SEAT_PATH=/org/freedesktop/DisplayManager/Seat0
nano ~/.config/scripts/monitor.sh
#!/bin/bash
dbus-monitor --session "type='signal',interface='org.gnome.ScreenSaver'" | \
(
while true; do
read X
if echo $X | grep "boolean true" &> /dev/null; then
echo `date` - SCREEN_LOCKED;
elif echo $X | grep "boolean false" &> /dev/null; then
#echo `date` - SCREEN_UNLOCKED;
DISPLAY=:0 xrandr --output eDP1 --scale 1.5x1.5
sleep 2
DISPLAY=:0 wmctrl -l|awk '{$3=""; $2=""; $1=""; print $0}'| xargs -I % sh -c '{ DISPLAY=:0 wmctrl -r "%" -b toggle,shaded; sleep 0.1; DISPLAY=:0 wmctrl -r "%" -b toggle,shaded; }'
sleep 1
killall dbus-monitor
killall monitor.sh
break
fi
done
)
D.) Optional Fix screen tearing for Intel GPUs
sudo vi /etc/X11/xorg.conf.d/20-intel.conf
Section "Monitor"
Identifier "Intel Graphics"
EndSection
Section "Device"
Identifier "Intel Graphics"
Driver "intel"
Option "TearFree" "true"
EndSection
And that’s it! You should now have a working Fractional HiDPI laptop running Ubuntu Budgie 20.04 under X11.