Using nixGL to fix OpenGL applications on non-NixOS distributions
The Nix package manager can be installed on any Linux distribution, on Mac and even on Windows. I’m currently using Ubuntu 20 and am enjoying home-manager to declaratively manage my $HOME
directory using Nix tooling. For instance, to use my favorite browser qutebrowser, I could just add it into my ~/.config/nixpkgs/home.nix
under packages
:
{ config, pkgs, ... }: { home.packages = [ pkgs.qutebrowser ]; }
However, since I also want to configure qutebrowser keybindings using home-manager, I’m using the builtin module instead:
{ config, pkgs, ... }: { programs.qutebrowser = { enable = true; keyBindings = { normal = { "m" = "spawn mpv {url}"; }; }; } }
Then I can home-manager switch
and voila, running qutebrowser
on a terminal…crashes! The output is…
(process:134810): Gtk-WARNING **: 17:55:45.724: Locale not supported by C library. Using the fallback 'C' locale. 17:55:45 WARNING: qglx_findConfig: Failed to finding matching FBConfig for QSurfaceFormat(version 2.0, options QFlags<QSurfaceFormat::FormatOption>(), depthBufferSize -1, redBufferSize 1, greenBufferSize 1, blueBufferSize 1, alphaBufferSize -1, stencilBufferSize -1, samples -1, swapBehavior QSurfaceFormat::SingleBuffer, swapInterval 1, colorSpace QSurfaceFormat::DefaultColorSpace, profile QSurfaceFormat::NoProfile) 17:55:45 WARNING: qglx_findConfig: Failed to finding matching FBConfig for QSurfaceFormat(version 2.0, options QFlags<QSurfaceFormat::FormatOption>(), depthBufferSize -1, redBufferSize 1, greenBufferSize 1, blueBufferSize 1, alphaBufferSize -1, stencilBufferSize -1, samples -1, swapBehavior QSurfaceFormat::SingleBuffer, swapInterval 1, colorSpace QSurfaceFormat::DefaultColorSpace, profile QSurfaceFormat::NoProfile) 17:55:45 CRITICAL: Could not initialize GLX Fatal Python error: Aborted Current thread 0x00007fd65318ef80 (most recent call first): File "/nix/store/krj21a11r9wbw2v9dpqkgfk6zrm88a43-qutebrowser-1.14.0/lib/python3.8/site-packages/qutebrowser/app.py", line 530 in __init__ File "/nix/store/krj21a11r9wbw2v9dpqkgfk6zrm88a43-qutebrowser-1.14.0/lib/python3.8/site-packages/qutebrowser/app.py", line 96 in run File "/nix/store/krj21a11r9wbw2v9dpqkgfk6zrm88a43-qutebrowser-1.14.0/lib/python3.8/site-packages/qutebrowser/qutebrowser.py", line 204 in main File "/nix/store/krj21a11r9wbw2v9dpqkgfk6zrm88a43-qutebrowser-1.14.0/bin/.qutebrowser-wrapped", line 9 in <module> Aborted (core dumped)
Something about GLX?
17:55:45 CRITICAL: Could not initialize GLX
The output of glxinfo
seems harmless. Is it a Nix problem, then. Let’s run:
nix-shell -p glxinfo --run glxinfo
This runs Nix’s version of glxinfo
, and indeed we get:
name of display: :0 Error: couldn't find RGB GLX visual or fbconfig
The problem faced here is, sadly, known (the linked issue was opened in 2015). There is a solution, however, in the form of guibou/nixGL. I won’t go into the details of how this works and just present you with the solution. For qutebrowser, it looks like this:
{ config, pkgs, ... }: let nixGLIntel = (pkgs.callPackage "${builtins.fetchTarball { url = https://github.com/guibou/nixGL/archive/17c1ec63b969472555514533569004e5f31a921f.tar.gz; sha256 = "0yh8zq746djazjvlspgyy1hvppaynbqrdqpgk447iygkpkp3f5qr"; }}/nixGL.nix" {}).nixGLIntel; in { programs.qutebrowser = { enable = true; keyBindings = { normal = { "m" = "spawn mpv {url}"; }; }; package = pkgs.writeShellScriptBin "qutebrowser" '' #!/bin/sh ${nixGLIntel}/bin/nixGLIntel ${pkgs.qutebrowser}/bin/qutebrowser "$@" ''; } }
So in the first few lines, I’m downloading a specific, pinned version of nixGL (so everything is nicely reproducible). I then wrap the qutebrowser
executable inside nixGLIntel
, as nixGL’s readme suggests. Then after another home-manager switch
, I can execute qutebrowser
without the error message.
Note that the setup is, of course, specific to me with my Intel GPU. There’s functions for NVidia and AMD, too.