rofi steam game list... and lots of other stuff
This commit is contained in:
parent
741a5dfb18
commit
6af0cdbacf
|
@ -1,15 +1,56 @@
|
|||
{ config, pkgs, lib, ... }:
|
||||
{
|
||||
# TODO: theme (it's using fish variables...)
|
||||
programs.fish = {
|
||||
programs.fish =
|
||||
let nom-compat = pkgs.runCommand "any-shell-nom-compat" {} ''
|
||||
mkdir -p $out/bin
|
||||
for cmd in $(echo nix nix-shell nix-build); do
|
||||
echo '#! ${pkgs.bash}/bin/bash' > $out/bin/$cmd
|
||||
echo -n 'PATH=`echo $PATH | tr ":" "\n" | grep -v "any-shell-nom-compat" | tr "\n" ":"` ' >> $out/bin/$cmd
|
||||
cmd1=$(echo $cmd | sed 's/nix/nom/')
|
||||
echo "$cmd1"' "$@"' >> $out/bin/$cmd
|
||||
chmod +x $out/bin/$cmd
|
||||
done
|
||||
'';
|
||||
in {
|
||||
enable = true;
|
||||
# not sure this is needed, but just in case
|
||||
shellInit = ''
|
||||
source /etc/fish/config.fish
|
||||
'';
|
||||
interactiveShellInit = ''
|
||||
${pkgs.any-nix-shell}/bin/any-nix-shell fish --info-right | source
|
||||
# ${pkgs.any-nix-shell}/bin/any-nix-shell fish | source
|
||||
|
||||
function nix-shell
|
||||
${pkgs.any-nix-shell}/bin/.any-nix-shell-wrapper fish $argv
|
||||
end
|
||||
function nix
|
||||
if test $argv[1] = shell
|
||||
set argv[1] fish
|
||||
${pkgs.any-nix-shell}/bin/.any-nix-wrapper $argv
|
||||
else if test $argv[1] = develop
|
||||
set argv[1] fish
|
||||
command nix develop --command $argv
|
||||
else
|
||||
command nix $argv
|
||||
end
|
||||
end
|
||||
|
||||
function nom-shell
|
||||
PATH="${nom-compat}/bin:$PATH" ${pkgs.any-nix-shell}/bin/.any-nix-shell-wrapper fish $argv
|
||||
end
|
||||
function nom
|
||||
if test $argv[1] = shell
|
||||
set argv[1] fish
|
||||
PATH="${nom-compat}/bin:$PATH" ${pkgs.any-nix-shell}/bin/.any-nix-wrapper $argv
|
||||
else if test $argv[1] = develop
|
||||
set argv[1] fish
|
||||
${pkgs.nix-output-monitor}/bin/nom develop --command $argv
|
||||
else
|
||||
command nix $argv
|
||||
end
|
||||
end
|
||||
|
||||
export NOMCOMPAT=${nom-compat}
|
||||
# for posix compatibility
|
||||
set -gx SHELL zsh
|
||||
|
||||
|
|
|
@ -56,12 +56,12 @@
|
|||
# for preview
|
||||
exa bat
|
||||
ffmpeg ffmpegthumbnailer nsxiv imagemagick
|
||||
libarchive unzip gnutar atool
|
||||
libarchive atool
|
||||
libreoffice poppler_utils fontpreview djvulibre
|
||||
glow w3m
|
||||
# for opening
|
||||
p7zip unrar-wrapper zathura mpv odt2txt
|
||||
];
|
||||
p7zip unrar-wrapper zathura odt2txt
|
||||
] ++ lib.optionals (!config.programs.mpv.enable) [ mpv ];
|
||||
plugins = {
|
||||
src = pluginSrc;
|
||||
mappings = {
|
||||
|
@ -144,6 +144,6 @@
|
|||
home.packages = with pkgs; [
|
||||
rclone sshfs fuse
|
||||
file jq python3Full killall
|
||||
appimage-run comma
|
||||
appimage-run comma nix-output-monitor
|
||||
];
|
||||
}
|
||||
|
|
|
@ -1,9 +1,31 @@
|
|||
{ config, pkgs, lib, ... }:
|
||||
{
|
||||
imports = [ ./terminal.nix ];
|
||||
i18n.inputMethod = let fcitx5-qt = pkgs.libsForQt5.fcitx5-qt; in {
|
||||
enabled = "fcitx5";
|
||||
fcitx5.addons = with pkgs; [ fcitx5-lua fcitx5-gtk fcitx5-mozc fcitx5-configtool fcitx5-qt ];
|
||||
};
|
||||
home.sessionVariables = {
|
||||
GTK_IM_MODULE = "fcitx";
|
||||
QT_IM_MODULE = "fcitx";
|
||||
XMODIFIERS = "@im=fcitx";
|
||||
SDL_IM_MODULE = "fcitx";
|
||||
XIM_SERVERS = "fcitx";
|
||||
INPUT_METHOD = "fcitx";
|
||||
SUDO_ASKPASS = pkgs.writeScript "sudo-askpass" ''
|
||||
#! ${pkgs.bash}/bin/bash
|
||||
${pkgs.libsecret}/bin/secret-tool lookup root password
|
||||
'';
|
||||
SDL_AUDIODRIVER = "pipewire,pulse,dsound";
|
||||
# SDL 3
|
||||
SDL_AUDIO_DRIVER = "pipewire,pulseaudio,dsound";
|
||||
ALSOFT_CONF = "${config.xdg.configHome}/.config/alsoft.conf";
|
||||
SDL_AUDIODRIVER = "pipewire";
|
||||
# TODO: set to sdl3 compat when SDL3 releases
|
||||
# this is for steam games, I set the launch options to:
|
||||
# `SDL_DYNAMIC_API=$SDL2_DYNAMIC_API %command%`
|
||||
# Steam itself doesn't work with SDL_DYNAMIC_API set, so it's
|
||||
# a bad idea to set SDL_DYNAMIC_API globally
|
||||
SDL2_DYNAMIC_API = "${pkgs.SDL2}/lib/libSDL2.so";
|
||||
};
|
||||
xdg.configFile."alsoft.conf".text = ''
|
||||
[general]
|
||||
|
@ -189,10 +211,6 @@
|
|||
];
|
||||
};
|
||||
};
|
||||
i18n.inputMethod = let fcitx5-qt = pkgs.libsForQt5.fcitx5-qt; in {
|
||||
enabled = "fcitx5";
|
||||
fcitx5.addons = with pkgs; [ fcitx5-lua fcitx5-gtk fcitx5-mozc fcitx5-configtool fcitx5-qt ];
|
||||
};
|
||||
services.gammastep.enable = true;
|
||||
fonts.fontconfig.enable = true;
|
||||
gtk = {
|
||||
|
|
|
@ -80,7 +80,7 @@ commonConfig = {
|
|||
inherit modifier;
|
||||
startup = [
|
||||
{ command = builtins.toString (with pkgs; writeShellScript "init-wm" ''
|
||||
${callPackage ./home-daemon.nix {}}/bin/dotfiles-home-daemon system76-scheduler&
|
||||
${callPackage ../home-daemon {}}/bin/dotfiles-home-daemon system76-scheduler&
|
||||
${gnome.zenity}/bin/zenity --password | (${keepassxc}/bin/keepassxc --pw-stdin ~/Nextcloud/keepass.kdbx&)
|
||||
# nextcloud and nheko need secret service access
|
||||
${nextcloud-client}/bin/nextcloud --background&
|
||||
|
@ -166,16 +166,6 @@ in
|
|||
imports = [ ./options.nix ./gui.nix ./waybar.nix ];
|
||||
home.sessionVariables = {
|
||||
_JAVA_AWT_WM_NONREPARENTING = "1";
|
||||
GTK_IM_MODULE = "fcitx";
|
||||
QT_IM_MODULE = "fcitx";
|
||||
XMODIFIERS = "@im=fcitx";
|
||||
SDL_IM_MODULE = "fcitx";
|
||||
XIM_SERVERS = "fcitx";
|
||||
INPUT_METHOD = "fcitx";
|
||||
SUDO_ASKPASS = pkgs.writeScript "sudo-askpass" ''
|
||||
#! ${pkgs.bash}/bin/bash
|
||||
${pkgs.libsecret}/bin/secret-tool lookup root password
|
||||
'';
|
||||
};
|
||||
xdg.configFile."xdg-desktop-portal-wlr/config".source = (pkgs.formats.ini {}).generate "xdg-desktop-portal-wlr.ini" {
|
||||
screencast = {
|
||||
|
@ -189,7 +179,7 @@ in
|
|||
systemd.user.services = lib.mkIf config.wayland.windowManager.sway.enable {
|
||||
gammastep.Unit.ConditionEnvironment = "WAYLAND_DISPLAY";
|
||||
};
|
||||
programs.mako = {
|
||||
services.mako = {
|
||||
enable = lib.mkDefault config.wayland.windowManager.sway.enable;
|
||||
# ms
|
||||
defaultTimeout = 7500;
|
||||
|
@ -336,7 +326,9 @@ in
|
|||
}; in commonConfig // swayConfig;
|
||||
extraSessionCommands = ''
|
||||
export WLR_RENDERER=vulkan
|
||||
export SDL_VIDEODRIVER=wayland
|
||||
export SDL_VIDEODRIVER=wayland,x11,kmsdrm,windows,directx
|
||||
# SDL3
|
||||
export SDL_VIDEO_DRIVER=wayland,x11,kmsdrm,windows
|
||||
export QT_QPA_PLATFORM=wayland
|
||||
export QT_WAYLAND_DISABLE_WINDOWDECORATION=1
|
||||
export QT_QPA_PLATFORMTHEME=gnome
|
||||
|
@ -345,12 +337,6 @@ in
|
|||
export GTK_USE_PORTAL=1
|
||||
export XDG_CURRENT_DESKTOP=sway
|
||||
export XDG_SESSION_DESKTOP=sway
|
||||
# TODO: set to sdl3 compat when SDL3 releases
|
||||
# this is for steam games, I set the launch options to:
|
||||
# `SDL_DYNAMIC_API=$SDL2_DYNAMIC_API %command%`
|
||||
# Steam itself doesn't work with SDL_DYNAMIC_API set, so it's
|
||||
# a bad idea to set SDL_DYNAMIC_API globally
|
||||
export SDL2_DYNAMIC_API=${pkgs.SDL2.out}/lib/libSDL2.so
|
||||
'';
|
||||
};
|
||||
services.swayidle = let swaylock-start = builtins.toString (with pkgs; writeScript "swaylock-start" ''
|
||||
|
@ -462,7 +448,7 @@ in
|
|||
};
|
||||
terminal = config.terminalBin;
|
||||
extraConfig = {
|
||||
modi = [ "calc" "drun" "run" "ssh" ];
|
||||
modi = [ "steam:${pkgs.callPackage ../rofi-steam-game-list {}}/bin/rofi-steam-game-list" "drun" "run" "ssh" ];
|
||||
icon-theme = "hicolor";
|
||||
drun-match-fields = [ "name" "generic" "exec" "keywords" ];
|
||||
show-icons = true;
|
||||
|
|
|
@ -19,13 +19,13 @@
|
|||
];
|
||||
# extraPython3Packages = pyPkgs: with pyPkgs; [ python-lsp-server ];
|
||||
extraConfig = ''
|
||||
autocmd BufReadPost * if @% !~# '\.git[\/\\]COMMIT_EDITMSG$' && line("'\"") > 1 && line("'\"") <= line("$") | exe "normal! g`\"" | endif
|
||||
syntax on
|
||||
au FileType markdown set colorcolumn=73 textwidth=72
|
||||
au FileType gitcommit set colorcolumn=73
|
||||
highlight NormalFloat guibg=NONE
|
||||
au BufReadPre * set foldmethod=syntax
|
||||
au BufReadPost * folddoc foldopen!
|
||||
autocmd BufReadPost * if @% !~# '\.git[\/\\]COMMIT_EDITMSG$' && line("'\"") > 1 && line("'\"") <= line("$") | exe "normal! g`\"" | endif
|
||||
'';
|
||||
viAlias = true;
|
||||
vimAlias = true;
|
||||
|
@ -40,6 +40,36 @@
|
|||
vim-svelte
|
||||
# TODO remove on next nvim update (0.8.3/0.9)
|
||||
vim-nix
|
||||
{ plugin = pkgs.vimUtils.buildVimPluginFrom2Nix {
|
||||
pname = "vscode-nvim";
|
||||
version = "2023-02-10";
|
||||
src = pkgs.fetchFromGitHub {
|
||||
owner = "Mofiqul";
|
||||
repo = "vscode.nvim";
|
||||
rev = "db9ee339b5556aa832ca58871fd18f9467a18520";
|
||||
sha256 = "sha256-X2IgIjO5NNq7vJdl09hBY1TFqHlsfF1xfllKr4osILI=";
|
||||
};
|
||||
};
|
||||
config = lua ''
|
||||
require("vscode").setup({
|
||||
transparent = true,
|
||||
color_overrides = {
|
||||
vscGray = "#745b5f",
|
||||
vscViolet = "#${config.colors.magenta}",
|
||||
vscBlue = "#6ddfd8",
|
||||
vscDarkBlue = "#${config.colors.blue}",
|
||||
vscGreen = "#${config.colors.green}",
|
||||
vscBlueGreen = "#73bf88",
|
||||
vscLightGreen = "#6acf6e",
|
||||
vscRed = "#${config.colors.red}",
|
||||
vscOrange = "#e89666",
|
||||
vscLightRed = "#e64e4e",
|
||||
vscYellowOrange = "#e8b166",
|
||||
vscYellow = "#${config.colors.yellow}",
|
||||
vscPink = "#cf83c4",
|
||||
},
|
||||
})
|
||||
''; }
|
||||
{ plugin = nvim-web-devicons;
|
||||
config = lua ''
|
||||
require'nvim-web-devicons'.setup {
|
||||
|
|
|
@ -8,11 +8,11 @@
|
|||
"utils": "utils"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1676367705,
|
||||
"narHash": "sha256-un5UbRat9TwruyImtwUGcKF823rCEp4fQxnsaLFL7CM=",
|
||||
"lastModified": 1677783711,
|
||||
"narHash": "sha256-eq5mOVk3gv5HITtLhPjKwi8bFnOaQplA3X0WFgHnmxE=",
|
||||
"owner": "nix-community",
|
||||
"repo": "home-manager",
|
||||
"rev": "da72e6fc6b7dc0c3f94edbd310aae7cd95c678b5",
|
||||
"rev": "b9e3a29864798d55ec1d6579ab97876bb1ee9664",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -28,11 +28,11 @@
|
|||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1676564857,
|
||||
"narHash": "sha256-E2O086asoR2sFhsEvPVCdneVYNoP1JbQ4B8OcIdpdPU=",
|
||||
"lastModified": 1677773085,
|
||||
"narHash": "sha256-TtNq5ooEUvyHMwOnFr1nUIpqzslM3pPGmbZKe+7BU4w=",
|
||||
"owner": "fufexan",
|
||||
"repo": "nix-gaming",
|
||||
"rev": "dbe7029d83ff8ab3db3e379c7a1fb65a309c5c54",
|
||||
"rev": "d59c534258d8d9779a5497e5a6a0f4e9616365ce",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -43,10 +43,10 @@
|
|||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1676795730,
|
||||
"narHash": "sha256-X69A9BdcPTySJJ7DqS4wc8b6eqGKi32jCSyaBsz4WB0=",
|
||||
"path": "/nix/store/wyanhqy905a9n7zy3syq5aiikd8y3ksl-source",
|
||||
"rev": "efc59894b1ba73cb745676616c56c780383d6788",
|
||||
"lastModified": 1677932085,
|
||||
"narHash": "sha256-+AB4dYllWig8iO6vAiGGYl0NEgmMgGHpy9gzWJ3322g=",
|
||||
"path": "/nix/store/qilsyakhi0qmjq9iwxn49g3qbl1rp5m7-source",
|
||||
"rev": "3c5319ad3aa51551182ac82ea17ab1c6b0f0df89",
|
||||
"type": "path"
|
||||
},
|
||||
"original": {
|
||||
|
@ -56,11 +56,11 @@
|
|||
},
|
||||
"nur": {
|
||||
"locked": {
|
||||
"lastModified": 1676785553,
|
||||
"narHash": "sha256-nJLp4LeU1MDfmyNkids+tIbpGx1tCwP4nI0gXOwKidg=",
|
||||
"lastModified": 1678002043,
|
||||
"narHash": "sha256-CKAoPQaUA+kitq4ChzlM5O3oTGHuQnlSV4hNSI1Ht0g=",
|
||||
"owner": "nix-community",
|
||||
"repo": "NUR",
|
||||
"rev": "15ac68824a1d403aa0da7a92618b3ac379f3cf71",
|
||||
"rev": "45ce037949e32a72bc65be6f20dc87fa73c5039d",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
|
@ -53,7 +53,7 @@
|
|||
home.packages = with pkgs; [
|
||||
openrgb piper
|
||||
steam-run steam
|
||||
osu-lazer-bin
|
||||
osu-lazer-bin taisei
|
||||
easyeffects
|
||||
# wineWowPackages.waylandFull
|
||||
winetricks
|
||||
|
|
1
home/rofi-steam-game-list/.gitignore
vendored
Normal file
1
home/rofi-steam-game-list/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
/target
|
225
home/rofi-steam-game-list/Cargo.lock
generated
Normal file
225
home/rofi-steam-game-list/Cargo.lock
generated
Normal file
|
@ -0,0 +1,225 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "block-buffer"
|
||||
version = "0.10.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "69cce20737498f97b993470a6e536b8523f0af7892a4f928cceb1ac5e52ebe7e"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "cpufeatures"
|
||||
version = "0.2.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crypto-common"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
"typenum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "digest"
|
||||
version = "0.10.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f"
|
||||
dependencies = [
|
||||
"block-buffer",
|
||||
"crypto-common",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fork"
|
||||
version = "0.1.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9788ce090af4bf8d6e8f43d3f7d12305c787456387bd2d88856fcda3aa1f0dca"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "generic-array"
|
||||
version = "0.14.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9"
|
||||
dependencies = [
|
||||
"typenum",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "keyvalues-parser"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7d990301996c856ea07a84bc291e76f1273db52683663efc05c8d355976897e5"
|
||||
dependencies = [
|
||||
"pest",
|
||||
"pest_derive",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.139"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79"
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.17.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3"
|
||||
|
||||
[[package]]
|
||||
name = "pest"
|
||||
version = "2.5.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8cbd939b234e95d72bc393d51788aec68aeeb5d51e748ca08ff3aad58cb722f7"
|
||||
dependencies = [
|
||||
"thiserror",
|
||||
"ucd-trie",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pest_derive"
|
||||
version = "2.5.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a81186863f3d0a27340815be8f2078dd8050b14cd71913db9fbda795e5f707d7"
|
||||
dependencies = [
|
||||
"pest",
|
||||
"pest_generator",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pest_generator"
|
||||
version = "2.5.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "75a1ef20bf3193c15ac345acb32e26b3dc3223aff4d77ae4fc5359567683796b"
|
||||
dependencies = [
|
||||
"pest",
|
||||
"pest_meta",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pest_meta"
|
||||
version = "2.5.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5e3b284b1f13a20dc5ebc90aff59a51b8d7137c221131b52a7260c08cbc1cc80"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"pest",
|
||||
"sha2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.51"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5d727cae5b39d21da60fa540906919ad737832fe0b1c165da3a34d6548c849d6"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rofi-steam-game-list"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"fork",
|
||||
"keyvalues-parser",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha2"
|
||||
version = "0.10.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cpufeatures",
|
||||
"digest",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.109"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.39"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a5ab016db510546d856297882807df8da66a16fb8c4101cb8b30054b0d5b2d9c"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.39"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5420d42e90af0c38c3290abcca25b9b3bdf379fc9f55c528f53a269d9c9a267e"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typenum"
|
||||
version = "1.16.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba"
|
||||
|
||||
[[package]]
|
||||
name = "ucd-trie"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9e79c4d996edb816c91e4308506774452e55e95c3c9de07b6729e17e15a5ef81"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
10
home/rofi-steam-game-list/Cargo.toml
Normal file
10
home/rofi-steam-game-list/Cargo.toml
Normal file
|
@ -0,0 +1,10 @@
|
|||
[package]
|
||||
name = "rofi-steam-game-list"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
keyvalues-parser = "0.1"
|
||||
fork = "0.1"
|
14
home/rofi-steam-game-list/default.nix
Normal file
14
home/rofi-steam-game-list/default.nix
Normal file
|
@ -0,0 +1,14 @@
|
|||
{ lib, rustPlatform }:
|
||||
rustPlatform.buildRustPackage {
|
||||
pname = "rofi-steam-game-list";
|
||||
version = "0.1";
|
||||
|
||||
src = ../rofi-steam-game-list;
|
||||
|
||||
cargoLock.lockFile = ../rofi-steam-game-list/Cargo.lock;
|
||||
|
||||
meta = with lib; {
|
||||
description = "A program to list Steam games for Rofi";
|
||||
license = licenses.bsd0;
|
||||
};
|
||||
}
|
510
home/rofi-steam-game-list/src/main.rs
Normal file
510
home/rofi-steam-game-list/src/main.rs
Normal file
|
@ -0,0 +1,510 @@
|
|||
//! I tried to create a proper parser, but those abstractions turned out to be not-so-zero cost!
|
||||
//! Here's a simple version instead
|
||||
#![allow(clippy::similar_names)]
|
||||
#![allow(clippy::cast_possible_truncation)]
|
||||
#![allow(clippy::needless_pass_by_value)]
|
||||
|
||||
use fork::daemon;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::io::{self, prelude::*};
|
||||
use std::sync::mpsc;
|
||||
use std::time::{Duration, SystemTime};
|
||||
|
||||
fn read_file(p: impl AsRef<std::path::Path>) -> io::Result<Vec<u8>> {
|
||||
let p = p.as_ref().to_owned();
|
||||
let mut vec = Vec::new();
|
||||
let mut file = std::fs::File::open(p)?;
|
||||
file.read_to_end(&mut vec)?;
|
||||
Ok(vec)
|
||||
}
|
||||
fn read_file_s(p: impl AsRef<std::path::Path>) -> io::Result<String> {
|
||||
let p = p.as_ref().to_owned();
|
||||
let mut s = String::new();
|
||||
let mut file = std::fs::File::open(p)?;
|
||||
std::io::Read::read_to_string(&mut file, &mut s)?;
|
||||
Ok(s)
|
||||
}
|
||||
|
||||
fn write_file(p: impl AsRef<std::path::Path>, data: Vec<u8>) -> io::Result<()> {
|
||||
let p = p.as_ref().to_owned();
|
||||
let mut file = std::fs::File::create(p)?;
|
||||
std::io::Write::write_all(&mut file, &data)
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct AppInfoEntry {
|
||||
pub app_id: u32,
|
||||
pub info_state: u32,
|
||||
pub last_updated: u32,
|
||||
pub pics_token: u64,
|
||||
pub text_vdf_sha1: [u8; 20],
|
||||
pub change_number: u32,
|
||||
pub info: HashMap<Vec<u8>, Value>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct AppInfo {
|
||||
pub magic: u32,
|
||||
pub universe: u32,
|
||||
pub entries: Vec<AppInfoEntry>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub enum Value {
|
||||
Map(HashMap<Vec<u8>, Value>),
|
||||
String(Vec<u8>),
|
||||
}
|
||||
|
||||
#[allow(clippy::missing_const_for_fn)]
|
||||
impl Value {
|
||||
fn into_map(self) -> Option<HashMap<Vec<u8>, Self>> {
|
||||
if let Self::Map(map) = self {
|
||||
Some(map)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
fn into_string(self) -> Option<Vec<u8>> {
|
||||
if let Self::String(s) = self {
|
||||
Some(s)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn read_map(reader: &mut impl io::Read) -> io::Result<HashMap<Vec<u8>, Value>> {
|
||||
let mut ret = HashMap::new();
|
||||
let mut buf = [0u8];
|
||||
let mut buf2 = [0u8; 2];
|
||||
let mut buf4 = [0u8; 4];
|
||||
let mut buf8 = [0u8; 8];
|
||||
loop {
|
||||
reader.read_exact(&mut buf)?;
|
||||
let kind = buf[0];
|
||||
if kind == 8 || kind == 11 {
|
||||
break Ok(ret);
|
||||
}
|
||||
let mut key = vec![];
|
||||
loop {
|
||||
reader.read_exact(&mut buf)?;
|
||||
if buf[0] == 0 {
|
||||
break;
|
||||
}
|
||||
key.push(buf[0]);
|
||||
}
|
||||
#[allow(clippy::match_same_arms)]
|
||||
match kind {
|
||||
0 => {
|
||||
ret.insert(key, Value::Map(read_map(reader)?));
|
||||
}
|
||||
1 => {
|
||||
let mut s = vec![];
|
||||
loop {
|
||||
reader.read_exact(&mut buf)?;
|
||||
if buf[0] == 0 {
|
||||
break;
|
||||
}
|
||||
s.push(buf[0]);
|
||||
}
|
||||
ret.insert(key, Value::String(s));
|
||||
}
|
||||
2 => {
|
||||
reader.read_exact(&mut buf4)?;
|
||||
// ret.insert(key, Value::I32(i32::from_le_bytes(buf4)))?;
|
||||
}
|
||||
3 => {
|
||||
reader.read_exact(&mut buf4)?;
|
||||
// ret.insert(key, Value::F32(f32::from_le_bytes(buf4)))?;
|
||||
}
|
||||
4 => {
|
||||
reader.read_exact(&mut buf4)?;
|
||||
// ret.insert(key, Value::Pointer(i32::from_le_bytes(buf4)))?;
|
||||
}
|
||||
5 => {
|
||||
let mut s = vec![0u16; 2];
|
||||
loop {
|
||||
reader.read_exact(&mut buf2)?;
|
||||
if buf2 == [0u8, 0u8] {
|
||||
break;
|
||||
}
|
||||
s.extend_from_slice(&[u16::from_le_bytes(buf2)]);
|
||||
}
|
||||
// utf-8 is used instead of utf-16 here
|
||||
// ret.insert(key, Value::WideString(s))?;
|
||||
}
|
||||
7 => {
|
||||
reader.read_exact(&mut buf8)?;
|
||||
// ret.insert(key, Value::U64(u64::from_le_bytes(buf8)))?;
|
||||
}
|
||||
10 => {
|
||||
reader.read_exact(&mut buf8)?;
|
||||
// ret.insert(key, Value::I64(i64::from_le_bytes(buf8)))?;
|
||||
}
|
||||
n => panic!("invalid vdf data type: {n}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn read_app_info(reader: &mut impl io::Read) -> io::Result<AppInfo> {
|
||||
let mut buf4 = [0u8; 4];
|
||||
// let mut buf8 = [0u8; 8];
|
||||
// let mut buf20 = [0u8; 20];
|
||||
let mut buf64 = [0u8; 64];
|
||||
reader.read_exact(&mut buf4)?;
|
||||
assert_eq!(buf4, [0x28, 0x44, 0x56, 0x07]);
|
||||
reader.read_exact(&mut buf4)?;
|
||||
assert_eq!(u32::from_le_bytes(buf4), 1);
|
||||
let mut ret = AppInfo {
|
||||
magic: 0x0756_4428,
|
||||
universe: 1,
|
||||
entries: vec![],
|
||||
};
|
||||
loop {
|
||||
reader.read_exact(&mut buf4)?;
|
||||
let app_id = u32::from_le_bytes(buf4);
|
||||
if app_id == 0 {
|
||||
break Ok(ret);
|
||||
}
|
||||
let mut entry = AppInfoEntry {
|
||||
app_id,
|
||||
info_state: 0,
|
||||
last_updated: 0,
|
||||
pics_token: 0,
|
||||
text_vdf_sha1: [0u8; 20],
|
||||
change_number: 0,
|
||||
info: HashMap::new(),
|
||||
};
|
||||
reader.read_exact(&mut buf64[..4 * 3 + 8 + 20 + 4 + 20])?;
|
||||
// reader.read_exact(&mut buf4)?;
|
||||
// size
|
||||
// reader.read_exact(&mut buf4)?;
|
||||
// entry.info_state = u32::from_le_bytes(buf4);
|
||||
// reader.read_exact(&mut buf4)?;
|
||||
// entry.last_updated = u32::from_le_bytes(buf4);
|
||||
// reader.read_exact(&mut buf8)?;
|
||||
// entry.pics_token = u64::from_le_bytes(buf8);
|
||||
// reader.read_exact(&mut buf20)?;
|
||||
// entry.text_vdf_sha1 = buf20;
|
||||
// reader.read_exact(&mut buf4)?;
|
||||
// entry.change_number = u32::from_le_bytes(buf4);
|
||||
// reader.read_exact(&mut buf20)?;
|
||||
// bin sha1
|
||||
entry.info = read_map(reader)?;
|
||||
ret.entries.push(entry);
|
||||
}
|
||||
}
|
||||
|
||||
fn home() -> String {
|
||||
std::env::var("HOME").unwrap()
|
||||
}
|
||||
fn xdg_home() -> String {
|
||||
std::env::var("XDG_DATA_HOME").unwrap_or_else(|_| home() + "/.local/share")
|
||||
}
|
||||
fn xdg_cache() -> String {
|
||||
std::env::var("XDG_CACHE_HOME").unwrap_or_else(|_| home() + "/.cache")
|
||||
}
|
||||
fn cache_dir() -> String {
|
||||
let dir = xdg_cache() + "/rofi-steam-game-list";
|
||||
let _ = std::fs::create_dir_all(&dir);
|
||||
dir
|
||||
}
|
||||
fn history_dir() -> String {
|
||||
let dir = xdg_home() + "/rofi-steam-game-list";
|
||||
let _ = std::fs::create_dir_all(&dir);
|
||||
dir
|
||||
}
|
||||
fn history(k: &str) -> HashMap<u32, u32> {
|
||||
let dir = history_dir();
|
||||
let mut ret = HashMap::new();
|
||||
let Ok(data) = read_file(dir + "/history_" + k) else {
|
||||
return ret;
|
||||
};
|
||||
if data.len() < 8 {
|
||||
return ret;
|
||||
}
|
||||
let count = u32::from_le_bytes(data[4..8].try_into().unwrap());
|
||||
let data = &mut &data[8..];
|
||||
let mut buf4 = [0u8; 4];
|
||||
for _ in 0..count {
|
||||
if std::io::Read::read_exact(data, &mut buf4).is_err() {
|
||||
return ret;
|
||||
}
|
||||
let k = u32::from_le_bytes(buf4);
|
||||
if std::io::Read::read_exact(data, &mut buf4).is_err() {
|
||||
return ret;
|
||||
}
|
||||
let v = u32::from_le_bytes(buf4);
|
||||
ret.insert(k, v);
|
||||
}
|
||||
ret
|
||||
}
|
||||
fn write_history(m: &HashMap<u32, u32>, k: &str) {
|
||||
let dir = history_dir();
|
||||
let mut data = vec![];
|
||||
data.extend_from_slice(&[0; 4]);
|
||||
data.extend_from_slice(&(m.len() as u32).to_le_bytes());
|
||||
for (k, v) in m.iter() {
|
||||
data.extend_from_slice(&k.to_le_bytes());
|
||||
data.extend_from_slice(&v.to_le_bytes());
|
||||
}
|
||||
let _ = write_file(dir + "/history_" + k, data);
|
||||
}
|
||||
|
||||
fn read_time(s: String) -> io::Result<SystemTime> {
|
||||
std::fs::metadata(s + "/Steam/appcache/appinfo.vdf")?.modified()
|
||||
}
|
||||
|
||||
fn read_appinfo(target_type: String, s: String) -> io::Result<(SystemTime, Vec<(u32, String)>)> {
|
||||
let time = read_time(s.clone())?;
|
||||
let vec = read_file(s + "/Steam/appcache/appinfo.vdf")?;
|
||||
let data = read_app_info(&mut &vec[..])?;
|
||||
let mut ret = Vec::new();
|
||||
for mut info in data.entries {
|
||||
if let Some(mut x) = info
|
||||
.info
|
||||
.remove(&b"appinfo"[..])
|
||||
.and_then(Value::into_map)
|
||||
.and_then(|mut x| x.remove(&b"common"[..]))
|
||||
.and_then(Value::into_map)
|
||||
{
|
||||
if let Some(mut t) = x
|
||||
.remove(&b"type"[..])
|
||||
.and_then(Value::into_string)
|
||||
.and_then(|x| String::from_utf8(x).ok())
|
||||
{
|
||||
if let Some(n) = x
|
||||
.remove(&b"name"[..])
|
||||
.and_then(Value::into_string)
|
||||
.and_then(|x| String::from_utf8(x).ok())
|
||||
{
|
||||
t.make_ascii_lowercase();
|
||||
if t == target_type {
|
||||
ret.push((info.app_id, n));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok((time, ret))
|
||||
}
|
||||
|
||||
fn list_appids(s: &str) -> HashSet<u32> {
|
||||
let Ok(data) = read_file_s(s.to_owned() + "/Steam/steamapps/libraryfolders.vdf") else {
|
||||
return HashSet::new();
|
||||
};
|
||||
let ret = keyvalues_parser::Vdf::parse(&data)
|
||||
.unwrap()
|
||||
.value
|
||||
.get_obj()
|
||||
.unwrap()
|
||||
.values()
|
||||
.flat_map(|x| {
|
||||
x.iter().flat_map(|x| {
|
||||
x.get_obj().unwrap().get("apps").into_iter().flat_map(|x| {
|
||||
x.iter().flat_map(|x| {
|
||||
x.get_obj()
|
||||
.unwrap()
|
||||
.keys()
|
||||
.filter_map(|x| x.parse::<u32>().ok())
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
.collect::<HashSet<u32>>();
|
||||
ret
|
||||
}
|
||||
|
||||
fn cache_time(k: &str) -> std::io::Result<SystemTime> {
|
||||
let path = cache_dir() + "/type_" + k;
|
||||
let mut file = std::fs::File::open(path)?;
|
||||
let mut data = Vec::new();
|
||||
file.read_to_end(&mut data)?;
|
||||
if data.len() >= 12 {
|
||||
let (_, data) = data.split_at(4);
|
||||
let (first, _data) = data.split_at(8);
|
||||
let time = SystemTime::UNIX_EPOCH
|
||||
+ Duration::from_millis(u64::from_le_bytes(first.try_into().unwrap()));
|
||||
Ok(time)
|
||||
} else {
|
||||
Err(io::Error::from(io::ErrorKind::Other))
|
||||
}
|
||||
}
|
||||
|
||||
fn read_cache(k: &str) -> io::Result<(SystemTime, Vec<(u32, String)>)> {
|
||||
let path = cache_dir() + "/type_" + k;
|
||||
let mut file = std::fs::File::open(path)?;
|
||||
let mut data = Vec::new();
|
||||
file.read_to_end(&mut data)?;
|
||||
if data.len() >= 16 {
|
||||
let (_, data) = data.split_at(4);
|
||||
let (first, data) = data.split_at(8);
|
||||
let time = SystemTime::UNIX_EPOCH
|
||||
+ Duration::from_millis(u64::from_le_bytes(first.try_into().unwrap()));
|
||||
let (first, data) = data.split_at(4);
|
||||
let count = u32::from_le_bytes(first.try_into().unwrap());
|
||||
let data = &mut &data[..];
|
||||
let mut buf4 = [0u8; 4];
|
||||
let mut buf1 = [0u8; 1];
|
||||
let mut ret = Vec::with_capacity(count as usize);
|
||||
for _ in 0..count {
|
||||
std::io::Read::read_exact(data, &mut buf4)?;
|
||||
std::io::Read::read_exact(data, &mut buf1)?;
|
||||
let len = if buf1[0] == 255 {
|
||||
std::io::Read::read_exact(data, &mut buf1)?;
|
||||
255 + buf1[0] as usize
|
||||
} else {
|
||||
buf1[0] as usize
|
||||
};
|
||||
let mut buf = vec![0; len];
|
||||
std::io::Read::read_exact(data, &mut buf)?;
|
||||
if let Ok(s) = String::from_utf8(buf) {
|
||||
ret.push((u32::from_le_bytes(buf4), s));
|
||||
}
|
||||
}
|
||||
Ok((time, ret))
|
||||
} else {
|
||||
Err(std::io::Error::new(
|
||||
std::io::ErrorKind::Other,
|
||||
"invalid app id cache format",
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
fn write_cache(k: &str, time: SystemTime, ids: &[(u32, String)]) {
|
||||
let mut data = Vec::new();
|
||||
data.extend_from_slice(&[0; 4]);
|
||||
data.extend_from_slice(
|
||||
&(time
|
||||
.duration_since(SystemTime::UNIX_EPOCH)
|
||||
.unwrap()
|
||||
.as_millis() as u64)
|
||||
.to_le_bytes(),
|
||||
);
|
||||
data.extend_from_slice(&(ids.len() as u32).to_le_bytes());
|
||||
for (id, s) in ids {
|
||||
if s.len() > u8::MAX as usize + u8::MAX as usize {
|
||||
continue;
|
||||
}
|
||||
data.extend_from_slice(&id.to_le_bytes());
|
||||
if s.len() > u8::MAX as usize {
|
||||
data.extend_from_slice(&255u8.to_le_bytes());
|
||||
data.extend_from_slice(&((s.len() - u8::MAX as usize) as u8).to_le_bytes());
|
||||
} else {
|
||||
data.extend_from_slice(&(s.len() as u8).to_le_bytes());
|
||||
}
|
||||
data.extend_from_slice(s.as_bytes());
|
||||
}
|
||||
let path = cache_dir() + "/type_" + k;
|
||||
if let Ok(mut file) = std::fs::File::create(path) {
|
||||
let _ = file.write_all(&data);
|
||||
}
|
||||
}
|
||||
|
||||
struct PendingFut;
|
||||
impl std::future::Future for PendingFut {
|
||||
type Output = ();
|
||||
fn poll(self: std::pin::Pin<&mut Self>, _: &mut std::task::Context<'_>) -> std::task::Poll<()> {
|
||||
std::task::Poll::Pending
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let target_type = std::env::args().nth(1).map_or_else(
|
||||
|| "game".to_owned(),
|
||||
|mut x| {
|
||||
x.make_ascii_lowercase();
|
||||
x
|
||||
},
|
||||
);
|
||||
if let Ok(appid) = std::env::var("ROFI_INFO") {
|
||||
let _ = daemon(true, false);
|
||||
let mut cmd = std::process::Command::new("xdg-open")
|
||||
.arg(&format!("steam://rungameid/{appid}"))
|
||||
.spawn()
|
||||
.unwrap();
|
||||
if let Ok(x) = appid.parse::<u32>() {
|
||||
let mut history = history(&target_type);
|
||||
history.entry(x).and_modify(|curr| *curr += 1).or_insert(1);
|
||||
write_history(&history, &target_type);
|
||||
}
|
||||
let _ = cmd.wait();
|
||||
return;
|
||||
}
|
||||
/*
|
||||
* Flow1: read app info -> print app info -> write cache
|
||||
* Flow2: read cache -> print cache -> check app info mod time -> write cache
|
||||
* */
|
||||
let xdg_home = xdg_home();
|
||||
let xdg_home2 = xdg_home.clone();
|
||||
let xdg_home3 = xdg_home;
|
||||
let target_type2 = target_type.clone();
|
||||
let target_type3 = target_type.clone();
|
||||
let target_type4 = target_type.clone();
|
||||
let a = std::thread::spawn(move || history(&target_type3));
|
||||
let (tx0, rx0) = mpsc::channel();
|
||||
let (tx2, rx2) = mpsc::channel();
|
||||
let b = std::thread::spawn(move || {
|
||||
let tx1 = tx0.clone();
|
||||
std::thread::spawn(move || {
|
||||
tx0.send(
|
||||
read_appinfo(target_type2, crate::xdg_home()).map_or_else(|_| {
|
||||
let _ = tx2.send(None);
|
||||
None
|
||||
}, |info| {
|
||||
let _ = tx2.send(Some(info.clone()));
|
||||
Some((info, false))
|
||||
})
|
||||
)
|
||||
});
|
||||
std::thread::spawn(move || tx1.send(read_cache(&target_type4).ok().map(|x| (x, true))));
|
||||
#[allow(clippy::same_functions_in_if_condition)]
|
||||
if let Ok(Some(x)) = rx0.recv() {
|
||||
x
|
||||
} else if let Ok(Some(x)) = rx0.recv() {
|
||||
x
|
||||
} else {
|
||||
panic!()
|
||||
}
|
||||
});
|
||||
let c = std::thread::spawn(move || list_appids(&xdg_home2));
|
||||
let history = a.join().unwrap();
|
||||
let ((time, app_info), is_cache) = b.join().unwrap();
|
||||
let installed_games = c.join().unwrap();
|
||||
|
||||
let mut app_info_2 = app_info
|
||||
.iter()
|
||||
.filter_map(|x| {
|
||||
if installed_games.contains(&x.0) {
|
||||
Some(x.clone())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
app_info_2.sort_by_key(|x| u32::MAX - history.get(&x.0).unwrap_or(&0));
|
||||
for (app_id, n) in &app_info_2 {
|
||||
let icon = format!("{xdg_home3}/Steam/appcache/librarycache/{app_id}_icon.jpg");
|
||||
print!("{n}\0info\x1f{app_id}");
|
||||
if std::fs::metadata(&icon).is_ok() {
|
||||
print!("\x1ficon\x1f{icon}");
|
||||
}
|
||||
println!();
|
||||
}
|
||||
let _ = daemon(true, false);
|
||||
if is_cache {
|
||||
if read_time(xdg_home3).unwrap() <= time {
|
||||
return;
|
||||
}
|
||||
if let Some((time, app_info)) = rx2.recv().unwrap() {
|
||||
write_cache(&target_type, time, &app_info);
|
||||
}
|
||||
} else {
|
||||
if let Ok(ctime) = cache_time(&target_type) {
|
||||
if time <= ctime {
|
||||
return;
|
||||
}
|
||||
}
|
||||
write_cache(&target_type, time, &app_info);
|
||||
}
|
||||
}
|
|
@ -94,13 +94,11 @@
|
|||
"vfio"
|
||||
"vfio_iommu_type1"
|
||||
"vfio_pci"
|
||||
"vfio_virqfd"
|
||||
] else []);
|
||||
initrd.availableKernelModules = lib.mkIf (!cfg.passGpuAtBoot) [
|
||||
"vfio"
|
||||
"vfio_iommu_type1"
|
||||
"vfio_pci"
|
||||
"vfio_virqfd"
|
||||
];
|
||||
extraModulePackages =
|
||||
with config.boot.kernelPackages;
|
||||
|
@ -118,8 +116,7 @@
|
|||
];
|
||||
kernelModules = [
|
||||
"vhost-net"
|
||||
] ++ (if cfg.passGpuAtBoot then [] else [ "vfio_virqfd" ])
|
||||
++ (if enableIvshmem then [ "kvmfr" ] else []);
|
||||
] ++ (if enableIvshmem then [ "kvmfr" ] else []);
|
||||
};
|
||||
services.udev.extraRules = lib.mkIf enableIvshmem
|
||||
(lib.concatStringsSep
|
||||
|
|
|
@ -52,11 +52,11 @@
|
|||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1676564857,
|
||||
"narHash": "sha256-E2O086asoR2sFhsEvPVCdneVYNoP1JbQ4B8OcIdpdPU=",
|
||||
"lastModified": 1677773085,
|
||||
"narHash": "sha256-TtNq5ooEUvyHMwOnFr1nUIpqzslM3pPGmbZKe+7BU4w=",
|
||||
"owner": "fufexan",
|
||||
"repo": "nix-gaming",
|
||||
"rev": "dbe7029d83ff8ab3db3e379c7a1fb65a309c5c54",
|
||||
"rev": "d59c534258d8d9779a5497e5a6a0f4e9616365ce",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -67,11 +67,11 @@
|
|||
},
|
||||
"nixos-hardware": {
|
||||
"locked": {
|
||||
"lastModified": 1676775543,
|
||||
"narHash": "sha256-VI0e60l94RY9Sc90OwDZpOf/nyLy41n2ULK6I6YkoP8=",
|
||||
"lastModified": 1677949148,
|
||||
"narHash": "sha256-dEdcn+UYs8TUK3VTNCQk9TsJapJLEq50A4q7eC3/PTU=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixos-hardware",
|
||||
"rev": "525177a78023e1363bee482f520d4f2471ada03a",
|
||||
"rev": "d63e86cbed3d399c4162594943bd8c1d8392e550",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -82,15 +82,16 @@
|
|||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1676795730,
|
||||
"narHash": "sha256-X69A9BdcPTySJJ7DqS4wc8b6eqGKi32jCSyaBsz4WB0=",
|
||||
"lastModified": 1677932085,
|
||||
"narHash": "sha256-+AB4dYllWig8iO6vAiGGYl0NEgmMgGHpy9gzWJ3322g=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "efc59894b1ba73cb745676616c56c780383d6788",
|
||||
"rev": "3c5319ad3aa51551182ac82ea17ab1c6b0f0df89",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nixos",
|
||||
"ref": "nixos-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
|
@ -113,11 +114,11 @@
|
|||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1676773870,
|
||||
"narHash": "sha256-RhG7QmA14xih1lv6SB2WDVER4fbJ1cLwr0ntCpIjKbQ=",
|
||||
"lastModified": 1677983714,
|
||||
"narHash": "sha256-2A5uDpF0vN4w9tvo5N+918bK0yRYfg4FdNZ/qccgH6s=",
|
||||
"owner": "oxalica",
|
||||
"repo": "rust-overlay",
|
||||
"rev": "a6fa42390d46ef1326fbe98288b65d3b586870da",
|
||||
"rev": "1a9f6285d441ff438a6a1422dc3fde109d8615bf",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
|
@ -2,8 +2,7 @@
|
|||
description = "NixOS configuration";
|
||||
|
||||
inputs = {
|
||||
# nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
|
||||
nixpkgs.url = "github:nixos/nixpkgs";
|
||||
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
|
||||
utils.url = "github:gytis-ivaskevicius/flake-utils-plus";
|
||||
nixos-hardware.url = "github:NixOS/nixos-hardware";
|
||||
impermanence.url = "github:nix-community/impermanence";
|
||||
|
|
|
@ -43,6 +43,7 @@ in {
|
|||
# resume_offset = $(btrfs inspect-internal map-swapfile -r path/to/swapfile)
|
||||
"resume_offset=533760"
|
||||
"fbcon=font:TER16x32"
|
||||
"consoleblank=60"
|
||||
];
|
||||
cleanTmpDir = true;
|
||||
loader = {
|
||||
|
|
Loading…
Reference in a new issue