The last few lines of the xtrace log show what is happening here at the protocol level: 000:<:0c81: 20: RANDR-Request(149,7): RandrSetScreenSize window=0x0000010c width=2640 height=800 width[mm]=699 height[mm]=212 000:<:0c82: 32: RANDR-Request(149,21): RandrSetCrtcConfig crtc=0x00000039 timestamp=0x1149c26e config timestamp=0x1149c26e x=1280 y=0 mode=0x00000223 rr=Rotate_0 outputs=0x0000003b; 000:>:0c82: Event RandrScreenChangeNotify(100) rotation=Rotate_0 timestamp=0x11498dd9 configTimestamp=0x1149c26e root=0x0000010c window=0x0000010c size-id=0xffff subpixelOrder=HorizontalRGB(0x0001) width[pixels]=2640 height[pixels]=800 width[mm]=699 height[mm]=212 000:>:0c82: Event ConfigureNotify(22) event=0x0000010c window=0x0000010c above-sibling=None(0x00000000) x=0 y=0 width=2640 height=800 border-width=0 override-redirect=false(0x00) 000:>:0c82: Event RandrScreenChangeNotify(100) rotation=Rotate_0 timestamp=0x11498dd9 configTimestamp=0x1149c26e root=0x0000010c window=0x0000010c size-id=0xffff subpixelOrder=HorizontalRGB(0x0001) width[pixels]=2640 height[pixels]=800 width[mm]=699 height[mm]=212 000:>:0c82: Event RandrChangeNotify1dot2(101) timestamp=0x11498dd9 request window=0x0000010c crtc affected=0x00000039 mode in use=0x00000223 new rr=Rotate_0 x=1280 y=0 width=1360 height=768 000:>:0c82: Event ConfigureNotify(22) event=0x0000010c window=0x0000010c above-sibling=None(0x00000000) x=0 y=0 width=2640 height=800 border-width=0 override-redirect=false(0x00) 000:>:0c82:32: Reply to RandrSetCrtcConfig: status=Success(0x00) 000:<:0c83: 32: RANDR-Request(149,21): RandrSetCrtcConfig crtc=0x0000003a timestamp=0x1149c26e config timestamp=0x1149c26e x=0 y=0 mode=0x0000003e rr=Rotate_0 outputs=0x0000003c; 000:>:0c83:32: Reply to RandrSetCrtcConfig: status=Success(0x00) 000:<:0c84: 12: RANDR-Request(149,30): RandrSetOutputPrimary window=0x0000010c output=0x00000000 000:<:0c85: 4: Request(37): UngrabServer 000:<:0c86: 4: Request(43): GetInputFocus 000:>:0c86:32: Reply to GetInputFocus: revert-to=Parent(0x02) focus=0x02a00004 *********************************** 000:<:0c87: 4: Request(36): GrabServer 000:<:0c88: 20: RANDR-Request(149,7): RandrSetScreenSize window=0x0000010c width=1280 height=800 width[mm]=339 height[mm]=212 000:<:0c89: 32: RANDR-Request(149,21): RandrSetCrtcConfig crtc=0x00000039 timestamp=0x11499b3d config timestamp=0x1149c26e x=0 y=0 mode=0x0000003e rr=Rotate_0 outputs=0x0000003b; 000:>:c88:Error 8=Match: major=7, minor=149, bad=268 There seems to be 2 separate events here (probably triggered by pressing Fn+F7 twice). The first event sets the screen size to 2640x800, with LVDS1 connected to CRTC 3a (positioned at x=0 and set to 1280x800), and VGA1 connected to CRTC 39 (which is positioned at x=1280 and set to 1360x768) The second event sets the screen size back down to 1280x800, before repositioning CRTC 39 (with VGA1 connected to it) to x=0 and setting it to 1280x800. The issue here is that the screen size is set to 1280x800 whilst CRTC39 is still displaying to an area beyond that - and this makes RandrSetScreenSize throw a BadMatch error ("All active monitors must be configured to display a subset of the specified size, else a Match error results") All the magic here happens in crtc_assignment_apply(). By this point, all outputs have been assigned to a CRTC, and the CRTC settings have already been computed. Firstly, this function determines the screen size required for the new CRTC settings. It *should* then iterate through each CRTC, and switch it off if it is currently displaying outside of the new screen size - but the xtrace log shows that this isn't happening. It then sets the new screen size (with RandrSetScreenSize, which we see happening), and then configures the CRTC's with their new settings (with RandrSetCrtcConfig) So, I need to figure out why CRTC39 isn't switched off before setting the new screen size, but that is for tomorrow.