I realise there are lots of other questions about this, but they are all about the basic setup. I have gotten most of the way there but I have a very specific question: I want to run full Unity on the external (HDMI) monitor, and I don't care if the laptop display is unusable.
I have a Dell XPS 15 with Nvidia GT 540M with Optimus. (DAMN OPTIMUS!!!!) I have Bumblebee installed. I am able to run the system on the laptop display, and I can use optirun to run programs like glxspheres in high-performance mode. When I plug in the external monitor, I see nothing, and xrandr
does not detect it ("HDMI1 disconnected (normal left inverted right x axis y axis)
").
Here's what I've done so far (working from Bumblebee's multi-monitor setup guide). I followed the "extra screen" advice there, so I have edited bumblebee.conf
and xorg.conf.nvidia
as instructed. Now, if I run:
export DISPLAY=:8 LD_LIBRARY_PATH=/usr/lib/nvidia-current:$LD_LIBRARY_PATH
optirun glxspheres
I see the glxspheres demo on the external monitor (without any window dressing). Woohoo!
Now the next step is to shut down Unity on the laptop display and test that glxspheres still works. So I hit Ctrl+Alt+F1 to go to the non-graphical terminal. Then:
sudo service lightdm stop
export DISPLAY=:8 LD_LIBRARY_PATH=/usr/lib/nvidia-current:$LD_LIBRARY_PATH
optirun glxspheres
Again, I see glxspheres on the external monitor.
Now the Bumblebee guide tells you to do "optirun wmii&
(or other like startlxde)" but I don't want to change to another window manager. How can I run Unity on the external monitor?
I tried optirun unity
and I got most of the way there. This starts up Unity on the external monitor. I can see the desktop, and the mouse works. I can run other programs inside Unity. There are just a couple of problems:
- Certain keyboard combinations don't get detected by Unity — looks like anything involving Ctrl as well as the Fn key. (e.g.: Ctrl+Alt+T didn't work to get a terminal; Fn+F11 didn't work to change the volume.)
- Keyboard strokes appear in the terminal as well as Unity. I don't want that since there may be passwords being typed.
- If I switch to another screen (e.g., Ctrl+Alt+F8), the audio stops working, so this is not a viable solution to #2.
I feel like these three issues are related. I think the main problem is that I shouldn't be directly running Unity, but instead, running lightdm. I've tried optirun lightdm
but it doesn't work at all. Hoping someone knows. If not, hopefully at least this question will help people almost-run Unity on an external monitor.
Best Answer
as I understand, Unity doesn't work with optirun (it seems to be a bug).
That's what I've found here:
HDMI doesn't work with Optimus hybrid graphics chipsets under Linux for most laptops, even if you use Bumblebee, but there is a way to get HDMI to work: by using a separate session.
Using the instructions below, you'll get an LXDE session (you can use XFCE or others, but the instructions below are for LXDE) to show up on the external monitor (which is connected via HDMI), and in this session, all the applications you launch use your laptop's Nvidia graphics card and you can play games, watch movies, etc. The LXDE session runs in the same time as your regular session, so on your laptop's screen you get your regular (main) session. Also, the mouse and keyboard are shared between the two sessions / monitors.
Here's how this looks like:
The first image above is from my laptop's screen (Dell XPS L702X which comes with Nvidia Optimus) while the second image is the separate LXDE session which is also running on my laptop, but is displayed on a TV connected via HDMI. As you can see, the first one is using the Intel graphics chip while the second one uses Nvidia.
However, there are some things to consider when using this:
Get HDMI to work with laptops using the Optimus technology under Ubuntu using Bumblebee and Synergy
Install Bumblebee if you haven't already.
Unity doesn't work with Bumblebee (and I'm not sure if you can run two sessions using the same window manager without them interfering anyway), so you'll need to use a different desktop environment / session, like LXDE, XFCE and so on - use whatever you want. I've used LXDE so using the instructions below, you'll get an LXDE session on the monitor connected via HDMI.
To get the mouse and keyboard working on the external monitor connected via HDMI we'll use Synergy, a tool that lets you share the mouse and keyboard between multiple computers.
Let's install the required packages (LXDE and Synergy):
sudo apt-get install synergy lxde lxde-common
To be able to use Synergy, you'll need to create a configuration file. You can download mine from HERE - copy the file to your home folder and rename it to ".synergy.conf" (notice the dot in front of the filename - that makes the file become hidden).
The file I've provided above should be enough, but if you want to change it, you can read about the Synergy configuration file here.
To start LXDE on the external monitor connected via HDMI, you can use a script which you can download from HERE. Extract the archive, copy the "hdmi" script to your home folder and make it executable using the following command:
chmod +x ~/hdmi
Now, to run the script, use the following command:
~/hdmi
LXDE should now start on the external monitor connected via HDMI. Give it some time (around 10 seconds) and moving your mouse to the left of your screen should make it show up on the HDMI device.
Here's what the script does (this is just an explaination, you don't need to run these commands, just use the above script):
exports the display to the one we're going to use for the HDMI monitor (8):
export DISPLAY=:8.0
runs LXDE with optirun (Bumblebee):
optirun startlxde &
runs the Synergy server in the foreground on the main display (on your laptop's main session) with 127.0.0.1 as the address:
synergys -f -a 127.0.0.1 --display :0 -n ubuntu &
runs the Synergy client in the foreground on the HDMI display and it connects it to the 127.0.0.1 server address:
synergyc -f -n hdmi --display :8 127.0.0.1 &
And finally, it exports the display back to your laptop's (main) display:
export DISPLAY=:0.0
The script also uses some "sleep" commands which add a delay to make sure the commands have enough time to get executed before running the next command.