Linux – How to use Xrandr to crop part of monitor off

linuxxorgxrandr

The very top of the physical monitor is obscured by a bezel (don't ask!). I want to use xrandr to redefine actual size of the desktop and so it only uses the usable portion of the monitor.

The actual pixel dimensions of the monitor is 2880×1920 but the top (say) 20 rows are not usable. (Actually it's less but I'll have to experiment). So I want a desktop that's 2880×1900 and set the monitor position such that the desktop is displayed on the monitor starting at row 20 and continuing to the bottom.

I think that means I need to use –pos +0-20 but I get:

$ xrandr  --output eDP-1 --pos +0-20
xrandr: failed to parse '+0-20' as a position

And I've tried other variations:

$ xrandr --fb 2880x1900 --output eDP-1 --size 2880x1900+0+20
xrandr: specified screen 2880x1900 not large enough for output eDP-1 (2880x1920+0+0)

This is very similar to an existing question How to use only part of a monitor for display but that user was asking about Windows and everyone suggests just using the window manager. That would get tiresome pretty quickly given that this is going to be always and for every workspace. I'm looking for a more fundamental solution.

Actually it looks like I'm wrong about it being less than 20 pixel rows.

I've found this:

$ xrandr --output eDP-1 --transform 1,0,0,0,1,-30,0,0,1 

does move the output down just right so that the top isn't cut off. Unfortunately now the whole desktop framebuffer extends below the visible screen. I could add a scale factor to that transform but I would rather just resize the desktop so that the bottom of the desktop lands at the bottom of the monitor.

Best Answer

  • My configuration:

    • Intel Celeron NUC
    • Ubuntu 18.04.3 LTS
    • Intel i915 drivers (integrated video)
    • HDMI output to an old LCD TV

    What didn't work:

    • Driver has no support for over/underscan properties in xrandr
    • Custom video modes still extended past the edges of the monitor

    What DID work:

    xrandr --output "HDMI-2" --fb 1800x1000 --transform 1,0,-60,0,1,-30,0,0,1
    

    --fb 1800x1000 sets the display area. Using this setting by itself will give you a large margin on the right and bottom, but does not center the image.

    --transform 1,0,-60,0,1,-40,0,0,1 shifts the displayed image to the right by 60 pixels (the -60) and down by 40 pixels (the -40).

    Combined together, my screen has a 60 pixel left margin, 1800 pixel wide display, and another 60 pixel right margin for a total with of 1920. Vertically, I have a 40 pixel top margin, a 1000 pixel tall display, and a 40 pixel bottom margin for a total of 1080.

    I still get the warning:

    xrandr: specified screen 1800x1000 not large enough for output HDMI-2 (1920x1080+-60+-40)
    

    However the frame buffer still gets resized and the transform is still applied so that the edges of the screen are no longer extended past the end of the monitor.

    Errorlevel after the xrandr is zero (meaning it worked without error) even through the above warning message is displayed.

    This is the solution that worked for me, and being on an Intel integrated video driver instead of the more advanced nVidia or Radeon drivers, it's the only solution that's work so far.

    For your resolution, I'd suggesting using a way smaller --fb to start with:

    xrandr --output eDP-1 --fb 2400x1800 
    

    Then play with the transforms to get the top left corner visible.

    Then figure out what you can expand your framebuffer to keep your right edge and bottom edge visible.

    None of this changes resolution, your screen is stil 2880x1920. You're just changing the screen size and shifting the screen down and to the right.

  • Related Question