Linux Dual Monitor Setup: Nvidia & Xinerama Guide: Rotating just one monitor

I have 2 LCD monitors (both are widescreen) hooked up to an Nvidia card in Linux. For a while, I rotated both of them into a “portrait” view, because, aside from the other benefits a portrait view can give (to webpages and documents), putting two widescreens on a landscape configuration takes up too much horizontal space.

But yesterday, I decided to take a hybrid approach and put my left monitor in landscape view, but my right one into portrait view — i.e., I only wanted one monitor rotated 90 degrees. Of course, this is fairly straightforward in Windows with the proprietary Nvidia utility, but it takes a little bit of work with Linux. I googled around a bit, and found this page. I couldn’t really understand what was going on by just looking at the sample xorg.conf file on that page, so I decided to write out my usual in-depth explanation on the matter.

First, to get this hybrid approach, you have to use Xinerama, and NOT Nvidia’s popular TwinView utility/configuration. This is because TwinView (in Linux) only allows you to rotate BOTH monitors together in the same direction.

The only thing you have to do is edit your /etc/X11/xorg.conf file. First, if you already have TwinView set up to work in a dual monitor configuration, you have to run sudo nvidia-settings, and then change from “TwinView” to “Separate X screen” under the “X Server Display Configuration” settings, like so:

2009-10-04-133053_914x657_scrot

The reason we do this (if you already have nvidia-settings installed) is because it auto-generates a working xorg.conf for us. The thing is, under TwinView, you just have 1 option for everything in Xorg — i.e., you just have Device0, Screen0, Monitor0, but now with the “Separate X screen”, you have Device1, Screen1, etc. Not only that, but your old, irrelevant TwinView settings will be automatically deleted or commented out, so it will save you a couple minutes of work (and any typos as well — typos will prevent X from booting!). After that, it’s just a matter of tweaking the xorg.conf file to suit your needs. (BTW, the reason why the right monitor looks like it’s not aligned vertically correctly with the one on the left is because of a manual adjustment — it’s the 333 pixel shift adjustment I made; read on below for more on that).

Here is my current, working xorg.conf with just 1 monitor rotated:

Section "ServerLayout"
Identifier     "Layout0"
#Screen      0  "Screen0" RightOf "Screen1" # put it on the RIGHT (other options are Below, Above, LeftOf, RightOf;
# alternatively, you can put an absolute, pixel X and Y offset (so RightOf
# would be 1680 0
Screen      0  "Screen0" 1680 0 # NOTE: Screen 0 MUST be defined BEFORE Screen 1!!!
Screen      1  "Screen1" 0 333 # put this screen on the top left, but adjust it down a little bit to match the portrait screen on the right
InputDevice    "Keyboard0" "CoreKeyboard"
InputDevice    "Mouse0" "CorePointer"
EndSection

Section "Files"
EndSection

Section "Module"
Load           "dbe"
Load           "extmod"
Load           "type1"
Load           "freetype"
Load           "glx"
EndSection

Section "ServerFlags"
Option         "AutoAddDevices" "False"
Option         "Xinerama" "1"
EndSection

Section "InputDevice"

# generated from default
Identifier     "Mouse0"
Driver         "mouse"
Option         "Protocol" "auto"
Option         "Device" "/dev/psaux"
Option         "Emulate3Buttons" "no"
#Option         "ZAxisMapping" "4 5" # for the Logitech MX 400
EndSection

Section "InputDevice"
Identifier     "Keyboard0"
Driver         "kbd"
Option         "XkbModel" "pc105"
Option         "XkbLayout" "us,fr,de"
Option         "XkbOptions" "grp:shifts_toggle"
EndSection

Section "Monitor"
Identifier     "Monitor0"
VendorName     "Unknown"
ModelName      "Acer X222W"
HorizSync       31.0 - 81.0
VertRefresh     56.0 - 75.0
Option         "DPMS"
Option         "Rotate" "Right" # for portrait mode
EndSection

Section "Monitor"
Identifier     "Monitor1"
VendorName     "Unknown"
ModelName      "Acer X222W"
HorizSync       31.0 - 81.0
VertRefresh     56.0 - 75.0
Option         "DPMS"
EndSection

Section "Device"
Identifier     "Device0"
Driver         "nvidia"
VendorName     "NVIDIA Corporation"
BoardName      "GeForce 8800 GTS"
Option         "RandRRotation" "on"
BusID          "PCI:1:0:0"
Screen          0 # i.e., the monitor on the RIGHT (physically)
EndSection

Section "Device"
Identifier     "Device1"
Driver         "nvidia"
VendorName     "NVIDIA Corporation"
BoardName      "GeForce 8800 GTS"
BusID          "PCI:1:0:0"
Screen          1 # the monitor on the LEFT (physically)
EndSection

Section "Screen"

Identifier     "Screen0"
Device         "Device0"
Monitor        "Monitor0"
DefaultDepth    24
Option         "metamodes" "DFP-0: 1680x1050 +0+0"
SubSection     "Display"
Depth       24
EndSubSection
EndSection

Section "Screen"
Identifier     "Screen1"
Device         "Device1"
Monitor        "Monitor1"
DefaultDepth    24
Option         "metamodes" "DFP-1: 1680x1050 +0+0"
SubSection     "Display"
Depth       24
EndSubSection
EndSection

Probably the most important options are the “Screen” options under the “ServerLayout” section — these define which monitor starts where, and the relationship between the two monitors. The “Screen” options are defined by a X-axis (horizontal) and Y-axis (vertical) offset — you can only use positive numbers, I think, and so this means that if a screen is defined as “0 0″, it is on the top left corner of the imaginary monitor “plane,” so to speak. I.e., increasing the X-axis offset moves your screen to the right, whereas increasing the Y-axis offset moves your screen down. For me, my left monitor is slightly adjusted down by 333 pixels, so that it matches up smoothly with my rotated monitor on my right (my setup, physically, looks like a sideways “T”). I’m not sure if the “RandRRotation” option is necessary — it probably is not — I’m too lazy to check after fiddling with my xorg.conf all day yesterday. The other options should be self-explanatory, along with the comments.

 

Here are some of the not-so-obvious details: for me, my “DFP-1″ is my LEFT monitor and “DFP-0″ is my RIGHT monitor. Apparently, the “primary display” is by default DFP-o (e.g., in Windows, the Nvidia utility detects DFP-o (my RIGHT monitor) as screen “1 of 2″, so I have to manually set DFP-1 (2 of 2) as my primary screen) — the only reason why I have it like this is because for some reason, my BIOS stuff shows up on DFP-1, and not the default “primary” DFP-0, and I’ve always liked my BIOS to show up on my LEFT screen by default — hence the reason why DFP-1 is on my left and DFP-0 is on my right. I hope that made sense. It probably didn’t, so here is a screenshot:

Each monitor has a resolution of 1680×1050, but now, my virtual desktop has a 2730×1680 resolution (1680 + 1050 = 2730). DFP-0 is physically rotated so that the bottom side sticks out to the far right — i.e., it’s rotated counter-clockwise 90 degrees — so that the clean, button-less bezel of its top area matches up nicely with the unrotated DFP-1. And so, we rotate “Right” under the “Monitor” section for Screen 0. This is probably the most sensible way for most people, since almost all monitors that do have buttons at all (to make an uneven, fatter bezel where the buttons are) have them at the bottom of the monitor.

Here are the advantages that you get with Xinerama in the above setup:

  • Moving the mouse from the right to the left is always continuous and seamless. This is even true when moving from the far edges of the portrait monitor into the widescreen one (see notes in screenshot). Finally, the virtual screen behaves EXACTLY like how the monitors look in the real world. (This behavior is available in Windows; however, there are two shortcomings that are not found in Xinerama: (1) when the mouse is on the top or bottom edge of the portrait monitor, your mouse becomes “stuck” and does not transition smoothly over to the widescreen monitor on the other side (see screenshot above); (2) even though you can adjust the monitors by simply dragging the icons around (which is very user-friendly, I must say), the adjustments are very course and you cannot adjust things down to the last pixel.)
  • Maximizing a window maximizes to the monitor’s area (i.e., the window maximizes up to either the landscape or portrait view), and not the big, virtual landscape of 2730×1680 pixels; even the applications behave intelligently!

A (temporary) disadvantage:

  • Since I’m using Xmonad as my window manager, popup dialog boxes automatically spawn to to the top-left of the virtual screen — i.e., if they’re small enough, they fit entirely into the unviewable area on the top edge. I have to manually flatten the image into the tiled area to see the contents of it. However, this is Xmonad’s fault, and there is probably a hack out there to fix this sort of thing. Even so, since I don’t really use GUI applications that have a lot of popup dialog boxes in the first place, this is a non-issue.

For a long time I thought that Xinerama was an ATI thing, but apparently, it works for Nvidia as well. The xorg.conf layout looks much nicer, and simpler with Xinerama, and is much more flexible with it (e.g., the 333 pixel shift). If you change the few lines in my xorg.conf above that deal with rotations, you could even do without TwinView as well and just use Xinerama for a basic dual-head setup without any rotated screens.

Minor Update, February 25, 2010: A comment in the screencap was incorrect. Thanks Bela!

(Belated) Update November 4, 2010: Removed obsolete bugs and workarounds (In short, commit 21ed660f30a3f96c787ab00a16499e0fb034b2ad was introduced in into the xserver code in the spring of 2010, and fixed this issue of left vs. right monitors b). Xorg 1.8.1.902 works perfectly fine with either monitor being rotated into portrait mode.

Update June 20, 2012: Nvidia driver version 302.17 has made some changes to how you describe which monitor to rotate. Here is my current Xorg file, called “10-dual-monitor-hybrid.conf” which lives under /etc/X11/xorg.conf.d:

Section "ServerLayout"
    Identifier     "Layout0"
    Screen      0  "Screen0" 0 0 # NOTE: Screen 0 MUST be defined BEFORE Screen 1!!!
    Screen      1  "Screen1" 1050 295 # push this screen down (vertically) 295 pixels from the top to match the portrait monitor on the left
    Option         "Xinerama" "1" # dual-head won't work properly without this!
EndSection

Section "Monitor"
    Identifier     "Monitor0"
    VendorName     "Unknown"
    ModelName      "Acer X222W"
    HorizSync       31.0 - 81.0
    VertRefresh     56.0 - 75.0
    Option         "DPMS"
EndSection

Section "Monitor"
    Identifier     "Monitor1"
    VendorName     "Unknown"
    ModelName      "Acer X222W"
    HorizSync       31.0 - 81.0
    VertRefresh     56.0 - 75.0
    Option         "DPMS"
EndSection

Section "Device"
    Identifier     "Device0"
    Driver         "nvidia"
    VendorName     "NVIDIA Corporation"
    BoardName      "GeForce 8800 GTS"
    BusID          "PCI:1:0:0"
    Screen          0 # i.e., the monitor on the LEFT (physically)
    Option "NoLogo" "1"
EndSection

Section "Device"
    Identifier     "Device1"
    Driver         "nvidia"
    VendorName     "NVIDIA Corporation"
    BoardName      "GeForce 8800 GTS"
    BusID          "PCI:1:0:0"
    Screen          1 # the monitor on the RIGHT (physically)
    Option "NoLogo" "1"
EndSection

Section "Screen"

    Identifier     "Screen0"
    Device         "Device0"
    Monitor        "Monitor0"
    DefaultDepth    24
    Option         "metamodes" "DFP-0: 1680x1050 +0+0 { Rotation=left }"
    SubSection     "Display"
        Depth       24
    EndSubSection
EndSection

Section "Screen"
    Identifier     "Screen1"
    Device         "Device1"
    Monitor        "Monitor1"
    DefaultDepth    24
    Option         "metamodes" "DFP-1: 1680x1050 +0+0"
    SubSection     "Display"
        Depth       24
    EndSubSection
EndSection

Notice that the screen rotation settings are now taken care of under the “metamodes” option in the “Screen” section of the monitor you want to rotate. The recent Xorg versions do not use the usual /etc/X11/xorg.conf file any more (it has been like that for many months).

About these ads

30 thoughts on “Linux Dual Monitor Setup: Nvidia & Xinerama Guide: Rotating just one monitor

  1. I’ve been meaning to do this for a few months and finally decided to today. Your post was the most useful explanation I read and changing my monitors’ orientation was easy; thanks a lot for taking the time to write it up.

  2. I wanted a very similar layout, except I wanted the _left_ monitor in portrait (vertical) mode. Shinobu’s directions allowed me to get it working pretty quickly. I post here my “ServerLayout” section — the rest is according to Shinobu and/or system- and hardware-specific. This is for 2ea 1920×1200 monitors. It includes an ASCII art chart of how the coordinates work out (I did this for my own understanding). The number 360 expresses where the two monitors are touching; you could set it higher if you wanted an “L” shaped display, lower for “r”. It only really matters if you care that the mouse pointer crosses between screens without a visual break, and sliced windows don’t look like they’re half underwater…

     72 Section "ServerLayout"
     73         Identifier     "Layout0"
     74         Screen      0  "Screen0" 1200 360    # Span: 1200x360 .. 3120x1560
     75         Screen      1  "Screen1"    0   0    # Span:    0x0   .. 1200x1920
     76 #
     77 #       Looks like:
     78 #                    1200
     79 #                   /    \
     80 #            0     /      \    1200
     81 #          0 +-------------------+              1920 = H
     82 #            |                   |\ 360        /    \
     83 #            |                   |/           /      \         3120
     84 #            |                   +-------------------------------+  360
     85 #            |                   |                               |
     86 #            |                   |                               |
     87 #          / |                   |                               | \
     88 #         /  |                   |                               |  \
     89 #       1920 |                   |                               | 1200 = V
     90 #         \  |                   |                               |  /
     91 #          \ |                   |                               | /
     92 #            |                   |                               |
     93 #            |                   |                               |
     94 #            |                   +-------------------------------+ 1560
     95 #            |                   |\                             ,
     96 #            |                   |/ 360 = (1/2 the difference between H & V)
     97 #       1920 +-------------------+                            /
     98 #             `                                              ,
     99 #              \                                            /
    100 #                - - - - - - - 3120 = (H + V) - - - - - - -
    101 #
    102 #           Vertical scale == 120 pixels / char (greatest common divisor)
    103 #         Horizontal scale ==  60 pixels / char (or it looks squashed)
    104 #
    105         InputDevice    "Keyboard0" "CoreKeyboard"
    106         InputDevice    "Mouse0" "CorePointer"
    107 EndSection
    
  3. BTW, in your graphic is a comment “*333, and not the more perfect ~262 pixels (1680/4) …”

    You must have meant 1050/4 (262.5). But I don’t see how either H/4 or V/4 is a more perfect offset for this purpose. The best offset is (H – V) / 2 — pinning the centers of the adjacent vertical sides. That’s 315 pixels for your 1680×1050 monitors. 333 is closer to that than to either side divided by 4 (262.5 & 420); only 18 pixels off from “perfect”.

  4. Ack I meant (1680 – 1050)/2 — and so it should be 315, not 262. You are entirely correct, Bela — thank you for your comments!! The graphic has been updated to reflect this.

    What follows is a verbose explanation of the same.

    The formula (1680 – 1050)/2 would be ideal because I’m adjusting the landscape monitor up/down along the long edge (the 1680 pixels edge) of the portrait mode monitor. That is, the “perfect” setup would be to have an exact, equal amount of pixels above and below, so that the landscape monitor lies exactly in the middle of the portrait one (315 pixels of deadspace above it, 315 pixels of deadspace below it in my case — leaving exactly 1050 pixels of space to be “occupied” by my landscape monitor along the long edge border of the portrait monitor). However, my monitor stand is not pixel-perfect, so I have to adjust the landscape monitor to a different number — in this case, 333 pixels.

  5. Of course — except that advice does not work at all if you have, as I do, a single solid, all-metal monitor stand with 2 adjustable arms that have a fixed height.

  6. You didn’t read the monitor stand’s technical specs about the 18-pixel gap between the arms ;-}

    [OT] WOW, WordPress has an utterly bizarre concept of “plain ASCII” email. It sent me your last comment as Content-Type: text/plain; charset=”UTF-8″; Content-Transfer-Encoding: quoted-printable; which is all vaguely plausible. After the UTF-8 content, with nothing to mark a transition, was ~6700 bytes of mostly high-bit gibberish. [/OT]

  7. For anyone that is having as hard a time as I did, the main difference between this config and everything else on google is this: You need to specify both “Rotate” and “RandRRotation.”

    Section “Monitor”
    Identifier “Monitor0″
    Option “Rotate” “Right” # for portrait mode
    EndSection

    Section “Device”
    Identifier “Device0″
    Option “RandRRotation” “on”
    EndSection

  8. Actually, like I stated in my April 10, 2010 update, you only need the “Rotate” option and not the “RandRRotation” option. Maybe you are using an older version of xorg, though. My current xorg.conf does not have any “RandRRotation” stuff in there at all, and I’m on xorg-server 1.8.1.902 (xorg-server 1.8.1.902-1 package on Arch Linux).

  9. Thank you so much for this excellent guide. I now can at long last browse the web in portrait mode on my old 4:3 17″ monitor while using my newer 19″ wide screen for other things!

  10. Unfortunately, this doesn’t work if you also want to have composite support, since the X server doesn’t allow both the xinerama and composite extensions at the same time. This means Compiz won’t work, for example.

  11. @Alex: I know, tell me about it! Some day, I hope Xinerama can support composite extensions (for me, I don’t care a straw for Compiz, but I would certainly LOVE to have true window transparency…). Until that day, Compiz/compositing and Xinerama will be mutually exclusive. Total bummer. :(

  12. I dont know for you, but for me it’s only working if the:

    Option “Rotate” “Right” # for portrait mode

    is in the device section, not the monitor section.

  13. @yorjo: Interesting; maybe it’s a xorg version issue? I’m on xorg-server 1.9.4 on Arch and I still have that option under the Monitor section. It could be a hardware issue, too.

    Anyway, thank you for your informative (corner case?) comment. It will help others, I’m sure.

  14. Thanks Shinobu, its a fantastic guide for rotation of the monitors screen. It did work for me as well just by using option “Rotate” “Right” # for portrait mode in the device section.

    I have two questions: How can i change the mouse Pointer movements from current up and down to right to the left, as we go from one screen to another? I have dual Twin monitors both monitors rotated to right (vertically). You mentioned something about Xinerama, what is it?

    Secondly, how to find the version for xorg-server?

  15. @Arsh

    RE: your first question: Let’s see, I actually did rotate both of my monitors into portrait mode before, too, although I rotated one right and one left (I used Xinerama since TwinView does not allow this). In your case, since you have both screens rotated in the same direction, you can use TwinView instead of Xinerama (it should be easier, too…).

    If you still want to use Xinerama for your setup instead of TwinView: I think you have to change the Screen variables under ServerLayout. So let’s say you have two screens, which both have 1680×1050 resolution. Because both of your screens are rotated to the right, the one on the left (let’s call it screen 0) will have a virtual resolution of 1050×1680. The screen on the right (let’s call it screen 1) also has resolution of 1050×1680. So there is a total resolution of 2100×3360. The key is that screen 1 has to occupy pixels from 1051 to 2100. This means that the one on the right will have to be placed 1050 pixels to the right. So you have something like this:

                        __ +1050 pixels to the right
                       /
                       |
                       |
    <-   0-1050  ->    <- 1051-2100 ->
    ***************    ***************
    * <- 1050 ->  *    *             *
    *             *    *             *
    *  .          *    *             *
    * /|\         *    *             *
    *  |          *    *             *
    *             *    *             *
    *  1          *    *             *
    *  6          *    *             *
    *  8          *    *             *
    *  0          *    *             *
    *             *    *             *
    *  |          *    *             *
    * \|/         *    *             *
    *  ` Screen 0 *    *   Screen 1  *
    ***************    ***************
    

    Try to put this in your “ServerLayout” section in your xorg.conf:

    Screen 0 "Screen0" 0 0 # MUST defined Screen 0 before Screen 1, or X server will crash! 
    Screen 1 "Screen1" 1050 0
    

    I think that’s right. Hopefully this will work for you (assuming your Screen 0 and Screen 1 are the same as in my example; they may be switched around so be careful). Oh, and you absolutely MUST define Screen 0 before Screen 1 as noted in my code snippet.

    RE: your second question: Read up your Linux distribution’s manual/documentation! I’ve only used Arch Linux extensively, and on Arch it’s just: sudo pacman -Q xorg-server

  16. I’ve been running this layout for a while, with a NVS 160M. Has anyone noticed CPU usage can be quite high from the X process? Not hugely high, just 5-10% average which is still much higher than normal.

    It appears worse when something like Chrome is running full screen on the rotated monitor.

  17. @Dan: I’m running xorg-server 1.10.4 (with Bela’s layout, comment #3 above). The X process idles at 0% CPU for me (I take it that you meant “idle” instead of “average”).

    Chromium does not add stress to the X process for me whether it’s full-screened on either the rotated or non-rotated monitor.

    Perhaps your set of xorg packages have bugs…?

  18. Thank you so much for the update. Just updated to Ubuntu 12.04 and subsequently updated to the new Driver Version 302.17. Spent a while wondering why my previous xorg.conf wasn’t working properly.

  19. Did not work for me quite well on OpenSuse 12.1 and NVidia – rotation did not work.
    Finally I managed to have primary screen left rotated, secondary in ladnscape through KDE settings (Configure desktop)

  20. Good news! Nvidia driver version 304.48 now supports Xrandr 1.2 and 1.3. This means that if you run this version of the driver, you can do your rotation and such via Xrandr. No more messing around with the xorg.conf files. Yay!!!! I just installed it on Kubuntu 12.04 via the xorg.edgers repository and then used xrandr to adjust the layout with my right monitor rotated, with compositing working.

    sudo add-apt-repository ppa:xorg-edgers/ppa && sudo apt-get update && sudo apt-get dist-upgrade

  21. @Jason: Wow, sounds great! I will try out the xrandr utility once the new Nvidia drivers hit Arch’s official repos (we’re still on 304.43).

  22. I have almost same configuration but also i got strange problem. :)

    I can’t place icons in rotated monitor lower than the height of main, non-rotated monitor.

    Also, Default placement of icons is towards one monitor, i can’t move icons to right display except manually.

    Any clue how to solve those two issues?

  23. @nardev: You’re probably using outdated xorg drivers. Seek help at your linux distro’s help forum; this blog is no longer active.

Comments are closed.