Post

NixOS build note - 02

NixOS build note - 02

nixos fcitx

在configuration.nix中设置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
  i18n.inputMethod = {
    enable = true;
    type = "fcitx5";
    fcitx5.waylandFrontend = true;
    fcitx5.addons = with pkgs; [
      # fcitx5-gtk
      fcitx5-rime
      qt6Packages.fcitx5-configtool
      fcitx5-rime

      fcitx5-nord 
      fcitx5-rose-pine
      fcitx5-material-color
    ];
  };

接着在home-manager中设置fcitx/rime的配置文件,link到系统中的位置. 当时我发现niri启动后不会自动开启fcitx5,于是在niri startup选项中手动”fcitx -d”. 但是接着遇到了一个奇怪的现象:在chrome中,fcitx的input box无法正确显示。

查阅nixos wiki后发现:

1
2
3
4
5
# https://wiki.nixos.org/wiki/Fcitx5

Fcitx5 Doesn't Start When Using WM
If using a Window Manager (WM), such as Sway, you may need to add services.xserver.desktopManager.runXdgAutostartIfNone = true; to your NixOS configuration.
If using a Window Manager (WM), such as Sway, you may need to add services.xserver.desktopManager.runXdgAutostartIfNone = true; to your NixOS configuration.

在configuration.nix中设置这个选项,然后删掉fcitx5在niri startup的部分,重启后正常工作.

无代理的情况如何rebuild

无意间把dae服务给关掉了, 没有代理就无法访问nixos的各个pkg,也就无法rebuild恢复。 可以在configuration.nix中增加清华镜像来应急,rebuild恢复代理后再将其注释掉

1
2
3
4
nix.settings.substituters = [
    "https://mirrors.tuna.tsinghua.edu.cn/nix-channels/store"       # tsinghua mirror
    "https://cache.nixos.org/"
];

将某个服务设置为开机不启动

想要dae开机不启动,但是如果只将enable = true删掉,发现这样服务就直接消失了。

正确做法:保留services.dae.enable=true的情况下,增加:

1
2
3
  systemd.services = {
    dae.wantedBy = lib.mkForce [];
  };

noctalia Light/Dark mode change in NixOS

I want to implement the light/dark mode change of noctalia by clicking mode button.

At first, I config my noctalia settings in programs.noctalia-shell.settings.

However, it turned out that only the first click works well, while the following failed.

The answer lies in nixos’s building formula: when you config a package in home-manager, normally it will first generate some immutable files under /nix/store (like /nix/store/-noctalia-settings.json) , then links them to right position (~/.config/noctalia/settings.json).

When clicking the toggle dark/light button, it will modify the ~/.config/notalia/settings.json and reload that file in noctalia. However, since it has been links to some immutable file under /nix/store, of course it will fail.

So the solution is clear: dont use the programs.noctalia-shell.settings so that we can let settings.json to be muttable. Instead, we can define a nix value of those config, converting nix-value to ultimate config manually(since it is settings.json, we can simply use bultin.toJSON).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
{
  pkgs,
  inputs,
  lib,
  ...
}: let
  noctaliaSettings = {
    # <ORIGINAL CONFIG>
    # ......
  };

  noctaliaSettingsSeed = pkgs.writeText "noctalia-settings-seed.json" (builtins.toJSON noctaliaSettings);
in {
  imports = [
    inputs.noctalia.homeModules.default
  ];

  home.file.".cache/noctalia/wallpapers.json" = {
    text = builtins.toJSON {
      defaultWallpaper = "${../images/sea.png}";
    };
  };

  # configure options
  programs.noctalia-shell = {
    enable = true;
    # Noctalia mutates settings.json at runtime. The upstream Home Manager
    # option writes it as a Nix store symlink, which breaks repeated toggles.
    settings = {};
  };

  home.activation.noctaliaSettingsSeed = lib.hm.dag.entryAfter ["writeBoundary"] ''
    settings_dir="$HOME/.config/noctalia"
    settings_file="$settings_dir/settings.json"

    $DRY_RUN_CMD mkdir -p "$settings_dir"

    if [ -L "$settings_file" ]; then
      target="$(readlink "$settings_file")"
      case "$target" in
        /nix/store/*)
          $DRY_RUN_CMD rm -f "$settings_file"
          $DRY_RUN_CMD cp ${noctaliaSettingsSeed} "$settings_file"
          $DRY_RUN_CMD chmod u+w "$settings_file"
          ;;
      esac
    elif [ ! -e "$settings_file" ]; then
      $DRY_RUN_CMD cp ${noctaliaSettingsSeed} "$settings_file"
      $DRY_RUN_CMD chmod u+w "$settings_file"
    fi
  '';
}

vscode无法打开”new folders”

/run/current-system/sw/share/xdg-desktop-portal/niri-portals.conf中有内容:

1
2
3
4
5
[preferred]
default=gnome;gtk;
org.freedesktop.impl.portal.Access=gtk;
org.freedesktop.impl.portal.Notification=gtk;
org.freedesktop.impl.portal.Secret=gnome-keyring;

这也是默认的配置. 但是当前的环境上并没有提供gnome,所以xdgyy优先使用portal-gnome的时候自然没有响应.

什么是xdg? xdg是一套跨桌面标准,包括:

  • 配置目录标准 由一系列环境变量设置:XDG_CONFIG_HOME(~/.config), XDG_DATA_HOME(~/.local/share), XDG_CACHE_HOME(~/.cache), XDG_STATE_HOME(~/.local/state)

  • .desktop文件标准 一般来自/usr/share/applications/xxx.desktop, ~/.local/share/applications/*.desktop
  • MIME类型和默认应用 比如png文件用什么打开
  • portal wayland下面,应用不能像x11一样能够随意窥探全局屏幕和输入,需要portal让桌面环境授权。一些常见的实现有:xdg-desktop-portal, xdg-desktop-portal-gnome, xdg-desktop-portal-kde, xdg-desktop-portal-gtk, xdg-desktop-portal-wlr.

解决方法:修改全局gtk设置:

1
2
3
4
5
6
7
8
9
  xdg.portal = {
    enable = true;
    extraPortals = [ pkgs.xdg-desktop-portal-gtk ];

    config.niri = {
      default = [ "gtk" ];    # use gtk
      "org.freedesktop.impl.portal.FileChooser" = [ "gtk" ];
    };
  };

###

This post is licensed under CC BY 4.0 by the author.