Qtile Hacking in nixos

I am new to nixos and after installing i have been using qtile. to customize my qtile i created a dev environment with help of direnv . i cloned the qtile repo and to check my config.py i have to run a xephyr script which spawns my config in a nested qtile window. Before me creating the virtual env using direnv i tried the normal approach of just adding the dependencies to my python packages in my configuration.nix file but when i add any python libraries in my configuration.nix python doesnot seem to have access to it in my user profile. i tried to install the dependencies using home-manager but then also there were some problems so i started using direnv and everything seems file. But now the problem is when i call the xephyr script to spawn a nested qtile with my config i am getting this error. i specified all the necessary dependencies in my shell.nix file but when i am ruuning the xephyr script i am getting this error

Traceback (most recent call last):
  File "/home/royaleinstein/.config/qtile/qtile/scripts/../bin/qtile", line 36, in <module>
    main()
  File "/home/royaleinstein/.config/qtile/qtile/libqtile/scripts/main.py", line 76, in main
    func(options)
  File "/home/royaleinstein/.config/qtile/qtile/libqtile/scripts/start.py", line 103, in start
    q = make_qtile(options)
  File "/home/royaleinstein/.config/qtile/qtile/libqtile/scripts/start.py", line 66, in make_qtile
    kore = libqtile.backend.get_core(options.backend)
  File "/home/royaleinstein/.config/qtile/qtile/libqtile/backend/__init__.py", line 46, in get_core
    return importlib.import_module(f"libqtile.backend.{backend}.core").Core(*args)
  File "/nix/store/c3cjxhn73xa5s8fm79w95d0879bijp04-python3-3.10.13/lib/python3.10/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1050, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1027, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1006, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 688, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 883, in exec_module
  File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
  File "/home/royaleinstein/.config/qtile/qtile/libqtile/backend/x11/core.py", line 38, in <module>
    from libqtile.backend import base
  File "/home/royaleinstein/.config/qtile/qtile/libqtile/backend/base/__init__.py", line 2, in <module>
    from libqtile.backend.base.drawer import Drawer  # noqa: F401
  File "/home/royaleinstein/.config/qtile/qtile/libqtile/backend/base/drawer.py", line 40, in <module>
    from libqtile import pangocffi, utils
  File "/home/royaleinstein/.config/qtile/qtile/libqtile/pangocffi.py", line 50, in <module>
    from libqtile.pango_ffi import pango_ffi as ffi
  File "/home/royaleinstein/.config/qtile/qtile/libqtile/pango_ffi.py", line 24, in <module>
    from cairocffi.ffi import ffi as cairocffi_ffi
ModuleNotFoundError: No module named 'cairocffi.ffi'
XIO:  fatal IO error 0 (Success) on X server ":1"                                                                                                                                                                    
      after 270 requests (268 known processed) with 42 events remaining.

what to do now ? need help i am new to nix i am loving it so far but small problems like this are not good

My solution to this problem was to just use the wayland backend.
With wayland you can just nest two sessions without any need for xephyr.
This is my wayland nixos module: https://github.com/Mic92/dotfiles/blob/b40c062aab8dd9a52f1797e8075f2b3c9180f146/nixos/modules/qtile.nix
And here the configuration: https://github.com/Mic92/dotfiles/blob/b40c062aab8dd9a52f1797e8075f2b3c9180f146/home/.config/qtile/config.py

To add python libraries I am using a python environment like this:

      pyEnv = pkgs.python3.withPackages (_p: [
        pkgs.python3.pkgs.qtile
        pkgs.python3.pkgs.iwlib
      ]);

(https://github.com/Mic92/dotfiles/blob/b40c062aab8dd9a52f1797e8075f2b3c9180f146/nixos/modules/qtile.nix#L110)

1 Like

at first i wanted to use wayland as well but qtile wayland doesnot have some functionality. so i am hesitant.

so i was thinking currently to test my config i am using qtile from github. so what happens if i use qtile from nix and copy the scripts from github to test my config. in the official qtile documentation they told to use the github clone to test your config but i think according to my research there are compatability issues with the git version and the one thats currently installed in my system. so if i want to hack with the qtile version from nix os how do i write my shell.nix to do that ?

You can get a development environment for qtile like this:

Save this as a shell.nix to get all dependencies of qtile

with import <nixpkgs> {};
pkgs.qtile.overrideAttrs (old: {
  buildInputs = [
    # optional dependencies go here
  ] ++ (old.buildInputs or []);
})

Then just run nix-shell

$ nix-shell

alternative would be to just use some virtualenv and pip install their dependencies:

I like using direnv’s envrc for that:

use nix -p python3
layout python

than pip install -e . or whatever buildsystem they use.
You might need to set LD_LIBRARY_PATH in if they use c libraries that are not included in the default python interpreter.

thank i got it working. i changed the script from qtile repo and it is now spawning a nested qtile without having to change to wayland. thanks for the help. i am also using direnv. now i need another help.
i am using emacs as my editor and i want to add qtile to my virtual env so that i my lsp can read it and give me completions. how can i do that ?

Just start emacs from the shell that has direnv loaded. It should than find the right python. The direnv script above already creates a virtualenv.