No Auto Resize with SPICE and virt-manager

The gnome desktop, mutter, has some hotplug code that deals with the resize.

If you have any other desktop like xfce4 or KDE or a bare .xinitrc file running compiz like I do, you are pretty stuck, but I think I finally found an elegant and easy solution.

xrandr --output Virtual-0 --auto will pick up the size and apply it from vdagent. All that's need is a trigger.

Here is the trigger and how to handle it.

udev exposes the resize event as a drm device change that looks like this:
UDEV [10758.537471] change /devices/pci0000:00/0000:00:02.0 `drm/card0 (drm)

To have your desktop react to it create a udev rule and refer to a script to resize:
Rule in /etc/udev/rules.d/50-x-resize.rules:

ACTION=="change",KERNEL=="card0", SUBSYSTEM=="drm", RUN+="/usr/local/bin/x-resize" 

Script in /usr/local/bin/x-resize:

#! /bin/sh
PATH=/usr/bin
export DISPLAY=:0.0
xrandr --output "$(xrandr | awk '/ connected/{print $1; exit; }')" --auto

You may need to customize that shell script for your situation.

I found that on debian 10 and Ubuntu 20.04 I didn't even have to restart anything; it picked it up immediately.

Update: 2021-03-17

I recently found that I had to get permissions to allow that script to work. I changed it to this:

#! /bin/sh 
PATH=/usr/bin
desktopuser=$(/bin/ps -ef  | /bin/grep -oP '^\w+ (?=.*vdagent( |$))') || exit 0
export DISPLAY=:0
export XAUTHORITY=$(eval echo "~$desktopuser")/.Xauthority
xrandr --output $(xrandr | awk '/ connected/{print $1; exit; }') --auto

I'm using Debian 10 and icewm as guest VM. When spice-vdagent is running I can manually adjust the screen size with xrandr --output Virtual-1 --auto

A change in the display size can also be observed with xev:

joe@l1:~$ xev -root -event randr 

RRScreenChangeNotify event, serial 18, synthetic NO, window 0x3af,
    root 0x3af, timestamp 39153, config_timestamp 82137
    size_index 65535, subpixel_order SubPixelUnknown
    rotation RR_Rotate_0
    width 1320, height 949, mwidth 348, mheight 250

RRNotify event, serial 18, synthetic NO, window 0x3af,
    subtype XRROutputChangeNotifyEvent
    output Virtual-1, crtc 63, mode 1320x949 (1320x949)
    rotation RR_Rotate_0
    connection RR_Connected, subpixel_order SubPixelUnknown

Using that as a trigger seems less intrusive than working with udev, in particular when using different desktop environments or window managers in the same VM.

joe@l1:~$ cat /home/joe/.xsession
#!/bin/sh

if [ -x /usr/bin/spice-vdagent ] ; then
    /usr/bin/spice-vdagent
    /home/joe/.icewm/xrandr-loop &
fi
exec /usr/bin/icewm-session

joe@l1:~$ cat /home/joe/.icewm/xrandr-loop
#!/bin/sh

sleep 2

xrandr --output "$(xrandr | awk '/ connected/{print $1; exit; }')" --auto

xev -root -event randr | \
grep --line-buffered 'subtype XRROutputChangeNotifyEvent' | \
while read foo ; do \
    xrandr --output "$(xrandr | awk '/ connected/{print $1; exit; }')" --auto
done

joe@l1:~$ 

go to the hardware section of your VM

Remove existing channel device if there is one and add the com.redhat.spice.0 spicevmc device