1

I am working on WSL2 (Ubuntu 20.04) and I have trouble setting up the $DISPLAY environment variable. More specificallly, I have a network configuration that allows me to ping devices connected to eth0, but I cannot run Qt apps.

(Edit: I run WSL2 on Windows 11)

When I run Qt software like Wireshark or in-house software from my company, I have this error message:

user@DESKTOP-XXX:~$ wireshark
qt.qpa.xcb : could not connect to display 0
qt.qpa.plugin: Couoldl not load the Qt platform plulgin "xcb" in "" even though it was found.

Looking this up, I understood that my $DISPLAY variable is not set properly. (I checked and the "xcb" plugin is installed and Qt locates it). I am now on a quest to understand the $DISPLAY envionment variable, and more specifically, how it works on WSL2. I found this great AskUbuntu answer about generalilties, but since WSL2 works a bit particularly (virtual machine, Hyper-V Virtual switch, etc), I can't understand what to set $DISPLAY to to communicate with something connected via Ethernet.

My network settings for WSL2:

I want to cmmunicate with a machine connected via Ethernet on my WSL2 computer. To do this, I set up the following configuration, that allows me to ping the machine:

  • Hyper-V virtual manager Windows app: WSL virtual switch set up as "External network" via the Ethernet connector I use
  • Network Connections Windows app:
    • Ethernet:
      • "Hyper-V extensible virtual switch" checked
    • vEthernet (WLS):
      • Hyper-V extenible virtual switch unchecked;
      • IPV4: IP 10.0.0.10, gateway 10.0.0.3, favorite DNS 0.0.0.0
  • Ubuntu network settings:
    • sudo ifconfig eth0 10.0.0.3 netmask 255.255.255.0
    • sudo ip route add default via 10.0.0.5 dev eth0

This setup allows me to ping my external machine via 10.0.0.2. (If I want to reach Internet via eth0, I need to add nameservers to resolv.conf.)

However, Qt apps still cannot reach it. And they cannot run at all. When I launch, for instance, Wireshark, I have the error message I stated above.

Some solutions I tried, inspired by things I found online:

user@DESKTOP-XXX:~$ export DISPLAY=0.0
qt.qpa.xcb : could not connect to display 0.0

user@DESKTOP-XXX:~$ export DISPLAY=8080 qt.qpa.xcb : could not connect to display 8080

user@DESKTOP-XXX:~$ export DISPLAY=10.0.0.2 qt.qpa.xcb : could not connect to display 10.0.0.2

user@DESKTOP-XXX:~$ export DISPLAY=10.0.0.2:0

infinite loading

  • Does this answer your question? Running GUI apps under WSL. You don't mention which Windows version you are running, but Windows 10 WSL does not include the ability to run GUI applications, although there are workarounds that you can configure. Since you don't mention having done any of those workaround (or running Windows 11, where DISPLAY would be set for you), I'm expecting that's your problem. Also see What's the easiest way to run GUI apps on Windows Subsystem for Linux?. – NotTheDr01ds Sep 09 '22 at 12:18
  • Thanks for your answer. This brings interesting elements to me. I'm running WSL2 on Windows 11. Thing is, I actually managed to get a Qt app running, without changing DISPLAY, but... After a reboot, nothing. I'll go through those links. – rss.clement Sep 09 '22 at 12:29
  • Hmm - Are you running any type of Systemd enablement script? Try wsl --shutdown, then restart Ubuntu with wsl ~ -e bash --norc --noprofie. Is the DISPLAY variable there at that point? – NotTheDr01ds Sep 09 '22 at 13:03
  • I just started WSL with these parameters and DISPLAY has the value of :0 . Moreso, xeyes work. C:\Users\me>wsl -e bash --norc --noprofile bash-5.0$ echo $DISPLAY :0 bash-5.0$ xeyes

    --> window open with the eyes.

    Great! Now I just have to see what is wrong in my usual Ubuntu bash.

    – rss.clement Sep 09 '22 at 13:11
  • Likely will be something in ~/.bashrc. Start by looking for a line that is modifying DISPLAY. – NotTheDr01ds Sep 09 '22 at 13:12
  • Good point, but nothing of the sort, grep DISPLAY returned nothing. I just have a few aliases (cmake, python, pip) in addition to default .bashsrc. That being said, I know realize that this is likely not the problem, because if I run export DISPLAY=:0, I still have: Error: Can't open display: :0 with xeyes and a similar message with wireshark. – rss.clement Sep 09 '22 at 13:22
  • Okay, then we're back to the network side. I thought that might have been a red-herring, but you're right that it's probably the root cause. I'll have to dig in deeper on it in a bit, but I'll definitely find time sometime today to see if I can spot the problem. – NotTheDr01ds Sep 09 '22 at 13:25
  • Thanks a lot mate, you are of great help for a network newbie such as I! I will keep digging on my end. – rss.clement Sep 09 '22 at 13:28
  • The network setup is "different", that's for sure. You should have been able to ping any device on your local network without those changes, but it wasn't working? Is there some other unique networking config (VPN?) that required you to make those changes in order to access local devices on eth0? – NotTheDr01ds Sep 09 '22 at 13:32
  • I can see why that might break WSLg -- It's likely relying on the switch that it configures in Hyper-V. Changing to this other route is likely problematic. There might be a way around it still, but not sure. – NotTheDr01ds Sep 09 '22 at 13:34
  • Well, I did change the Hyper-V and network configuration, as I stated in the post. But it resets each time I reboot, and if I want to ping 10.0.0.2 from Ubuntu, I have to set it up like that again. But you're right, I can see that being a problem, especially since last week I could run Qt apps (maybe I had forgotten to change the config?). That's a good lead, buut I tried again after rebot and still nothing. Hmm... Oh and to make sure, I disabled all firewalls on Windows and Ubuntu. I don't use a VPN. – rss.clement Sep 09 '22 at 13:39
  • Quick update, after a reboot, I retried wsl ~ -e bash --norc --noprofie and this time, xeyes returns Error: Can't open display: :0. I'm perplexed, I will dig more on Monday. – rss.clement Sep 09 '22 at 15:05
  • Hey again. I would like to know what happens in system parameters when I start WSL2. I asksed this question: https://askubuntu.com/questions/1428910/wsl2-seems-to-change-network-configuration-or-display-variable-on-start-up-wher to get a bit more insight on it. – rss.clement Sep 12 '22 at 08:51

4 Answers4

0

I believe the problem may be actually occurring in the WSLg "system distribution" rather than in Ubuntu itself. Note that at this point, this is purely a theory -- a theory with a lot of supporting information, but still a theory.

As background, when you start a WSL2 distribution under Windows 11, two distributions are actually started:

  • The main distribution (e.g. Ubuntu)
  • A corresponding system distribution for each "main" distribution. This distribution is actually a Microsoft CBL-Mariner distribution.

Interestingly, for X applications to work in WSL2, you don't even need a network connection from Ubuntu itself. I was able to start Ubuntu, take down eth0, delete all routes, and I could still launch X applications. This is because Ubuntu is linked to the WSLg distribution through a symlink (or in Preview releases, a bind mount) of the X11 socket in /tmp/.X11-Unix/ to /mnt/wslg/.X11-Unix.

What's probably more important is the networking inside that system distribution. I have a feeling that it isn't able to make the proper connections due to the networking changes you mention.

In some quick trials on my end, I'm getting the feeling that you won't be able to "fix" the network at runtime. You can certainly try, and I encourage you to, by launching:

wsl --system -u root

But I wasn't able to "break" it by tearing down network connections myself, and my guess is that this is because the network connections are already established when the system distribution started. From the readme:

WSLGd is the first process to launch after init.

So it seems that we'll need to tear down any existing WSLGd (along with the Weston, XWayland, and Pulse subprocesses) and relaunch it/them after fixing the networking. I haven't gotten that far myself, but perhaps you'll have better success. At this point, if I stop the existing WSLGd, et. al., and restart it, I'm not able start X apps even without any other changes. So getting a basic stop and restart working will be the next step.

Ultimately, I have a feeling that, to permanently fix the issue (if I'm even on the right track with the issue), that you'll need to build your own system distribution with the networking changes already in place.

But that's today's theory. Hopefully I'm overthinking it, and you'll find it's something much more straightforward.

NotTheDr01ds
  • 17,888
0

Throwing this out as another answer (workaround) if you want to go this route. It doesn't "fix" the problem, but you should be able to fall back to the "Windows 10" way of getting X running, which is to either:

  • Install a third-party X server such as VcXsrv (or one of many others)
  • Run via XRDP

That would take WSLg out of the picture, and allow you to run as long as you have a proper network connection between the Windows host and WSL2.

Some details in:

WSLg is nice, but if you need that custom networking configuration, and you can't get WSLg working with it, it's nice to have the "fallbacks" at least.

NotTheDr01ds
  • 17,888
  • Thanks for this answer. I may resort to this, but I am frustrated because my apps worked last week, without a X server. I feel like I just need to revert to the configuration I had when it did. But I'm definitely keeping this solution in mind in case I don't make any progress. – rss.clement Sep 12 '22 at 08:27
  • This actually worked. Installing VcXsrv, then launching a server via XLaunch with 0 as the display. Thank you for all the help! – rss.clement Sep 23 '22 at 09:46
0

Ok, here's another possibility now that I can reproduce this to some extent.

If you are running the latest WSL Preview (0.66.2), then there's a known WSLg issue that causes the X11 socket to be recreated while the old one still exists. This leads the system distribution (see my earlier answer for details) to increment the display number (since the old one is locked).

Check:

ls /tmp/.X11-unix

If this is the issue you are experiencing, then you'll see something other than X0 when the problem is occurring.

You should able to temporarily recover by setting the DISPLAY to whatever number follows the X. For instance, if you have X2, then:

export DISPLAY=:2

Then try xeyes or wireshark.

What I haven't figured out yet is all of the various things that can trigger the issue. In my case, I can easily reproduce it by:

wsl --terminate Ubuntu

... then quickly restarting. This causes a timing issue where the system distro is still running.

As you can see in that issue report, the WSLg team is aware of the problem and will be reverting the change in the next release.

NotTheDr01ds
  • 17,888
  • Well! That's very interesting, I have nothing in /tmp/.X11-unix. ls /tmp/.X11-unix/ returns nothing. This is very likely linked to my DISPLAY error. Thanks for the lead! – rss.clement Sep 13 '22 at 07:34
  • @rss.clement Have I asked you already if you are using something to enable Systemd? Its tmpfiles configuration has a tendency to wipe out the WSLg X socket, because it wasn't created through Systemd. That could be, in one of your questions, you mentioned that "it worked for a bit then stopped" (or something like that). – NotTheDr01ds Sep 13 '22 at 11:43
  • Absolutely, great point. A software I installed needed me to change the backlog size. So I installeld this from GitHub: https://github.com/DamionGans/ubuntu-wsl2-systemd-scriptand ran it. – rss.clement Sep 13 '22 at 14:06
  • @rss.clement Oh wait - I did ask you, in my second comment on your question! ;-) And yes, that'll do it! The Systemd tmpfiles unit is erasing the X socket. I typically recommend against Systemd scripts for this reason (and others). That may be why it initially worked when starting with the --noprofile --norc flags -- You are probably starting the Systemd namespace somewhere in your startup files? – NotTheDr01ds Sep 13 '22 at 14:42
  • That's an amazing lead, I'm so sorry I imissed it. I have nothing in my .bashrc, do you know where I can find additional startup files? Edit: stupid question, sorry. Checking .profile – rss.clement Sep 13 '22 at 15:15
  • @rss.clement Also check /etc/profile and /etc/profile.d/*. Try grep -ri systemd in your home directory and the /etc/profile.d directory. Don't do it in /etc/ as there will be too many "normal" occurrences. – NotTheDr01ds Sep 13 '22 at 15:34
  • Hmm, nothing at all, in .bashrc, in .profile, in /etc/profile, in /etc/profile.d/*... This is getting confusing – rss.clement Sep 14 '22 at 13:17
  • @rss.clement I think you mentioned launching from a shortcut or icon? Any chance that has a command line or script that runs the Systemd script? – NotTheDr01ds Sep 14 '22 at 14:43
  • I got our app to open!!! I actually installed VcxServ, added a custom rule in Windows Defender Firewall, then started XLaunch with display=0 and "disable remote access" checked. Then started WSL2, set DISPLAY to my default IP route, and voilà. I'll check everything works tomorrow and then edit/close the question. Thanks for your hel!! – rss.clement Sep 14 '22 at 15:11
0

I'm on windows 10 and running wsl Ubuntu.

Try sudo apt install libxcb-xinerama0

This worked for me beautifully. Especially after so many hours of trying.